簡體   English   中英

正確的方法來組織SIZE_T *?

[英]Correct way to marshal SIZE_T*?

我有以下C ++函數定義,我試圖通過托管代碼通過PInvoke調用:

bool FooBar(SIZE_T* arg1);

我的管理聲明如下:

[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref uint arg1);

有些人可能會注意到我最終做的同樣的錯誤。 這不是64位便攜式。 SIZE_T的大小可變(32-64位),指針也是如此。 在托管大小上,指針正確轉換為64位,但uint沒有,並且您最終可以在arg1的高位中使用垃圾。 這是一個特別持久的錯誤,因為垃圾通常只是零:(

我已經開始工作的唯一解決方案是以下管理聲明:

[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref IntPtr arg1);

這當然有效,因為IntPtr可以正確地改變它的大小。 在我的代碼中,我只是將IntPtr視為一個整數,它可以工作,雖然它看起來像一個丑陋的黑客。 在我看來應該有一些方法來正確指定,也許使用UnmanagedType.SysUInt,但我無法提出任何其他工作解決方案。

使用IntPtr和/或UIntPtr 適當做-的類型有專門用於此目的! 我不明白為什么你認為這是一個“丑陋的黑客”。 我也不確定你提議的替代方案是什么 - 允許將值映射到uint任何類型的屬性本質上都是錯誤的,因為無論架構如何,C# uint都保證是32位的,所以64-位平台,要正確編組它,它必須修剪一半,丟失數據,並可能使結果無用。

UIntPtr是要使用的正確類型。

size_t是一個無符號的,指針大小的整數,這正是UIntPtr的含義。 我同意,名字中的“ptr”可能有點令人困惑。 它實際上並不意味着“這是一個指針”,它意味着“這是一個指針大小的整數”。 所以你的聲明是:

[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref UIntPtr arg1);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM