Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 映射特定于平台的可互操作类型_C#_C++_.net_Interop_Pinvoke - Fatal编程技术网

C# 映射特定于平台的可互操作类型

C# 映射特定于平台的可互操作类型,c#,c++,.net,interop,pinvoke,C#,C++,.net,Interop,Pinvoke,参考文件列出了以下类型: #if defined(_WIN64) typedef __int64 INT_PTR; #else typedef int INT_PTR; #endif #if defined(_WIN64) typedef __int64 LONG_PTR; #else typedef long LONG_PTR; #endif 由于.NET(大部分)取消了预处理器指令,因此要精确地映射这些指令并不容易。我可以看到两种选择,我想知道哪一种最好: 使用IntPt

参考文件列出了以下类型:

#if defined(_WIN64) 
 typedef __int64 INT_PTR; 
#else 
 typedef int INT_PTR;
#endif

#if defined(_WIN64)
 typedef __int64 LONG_PTR; 
#else
 typedef long LONG_PTR;
#endif
由于.NET(大部分)取消了预处理器指令,因此要精确地映射这些指令并不容易。我可以看到两种选择,我想知道哪一种最好:

使用IntPtr,因为它是特定于平台的

using INT_PTR = System.IntPtr;
using LONG_PTR = System.IntPtr;

使用较大的整数,以防在x64上运行

using INT_PTR = System.Int64;
using LONG_PTR = System.Int64;
我的直觉是使用
IntPtr
而不是
Int64
,不过我想了解一下什么才是最好的选择

备注


问题:你想解决什么问题?
回答:通常将windows数据类型映射到.NET,尽可能紧密地支持未来的PInvoke操作

问题:PInvoke与这个问题有什么关系?
回答:将托管数据正确映射到PInvoke/d(非托管)签名(将来使用)需要windows数据类型

示例:

LRESULT WINAPI SendMessage(
  _In_  HWND hWnd,
  _In_  UINT Msg,
  _In_  WPARAM wParam,
  _In_  LPARAM lParam
);
[DllImport("user32.dll", CallingConvention = CallingConvention.Winapi)]
public static extern IntPtr SendMessage(
    [In] IntPtr hWnd,
    [In] uint Msg,
    [In] UIntPtr wParam,
    [In] IntPtr lParam
);

[DllImport("user32.dll", CallingConvention = CallingConvention.Winapi)]
public static extern long SendMessage(
    [In] IntPtr hWnd,
    [In] uint Msg,
    [In] ulong wParam,
    [In] long lParam
);
本机声明:

LRESULT WINAPI SendMessage(
  _In_  HWND hWnd,
  _In_  UINT Msg,
  _In_  WPARAM wParam,
  _In_  LPARAM lParam
);
[DllImport("user32.dll", CallingConvention = CallingConvention.Winapi)]
public static extern IntPtr SendMessage(
    [In] IntPtr hWnd,
    [In] uint Msg,
    [In] UIntPtr wParam,
    [In] IntPtr lParam
);

[DllImport("user32.dll", CallingConvention = CallingConvention.Winapi)]
public static extern long SendMessage(
    [In] IntPtr hWnd,
    [In] uint Msg,
    [In] ulong wParam,
    [In] long lParam
);
平沃克声明变体:

LRESULT WINAPI SendMessage(
  _In_  HWND hWnd,
  _In_  UINT Msg,
  _In_  WPARAM wParam,
  _In_  LPARAM lParam
);
[DllImport("user32.dll", CallingConvention = CallingConvention.Winapi)]
public static extern IntPtr SendMessage(
    [In] IntPtr hWnd,
    [In] uint Msg,
    [In] UIntPtr wParam,
    [In] IntPtr lParam
);

[DllImport("user32.dll", CallingConvention = CallingConvention.Winapi)]
public static extern long SendMessage(
    [In] IntPtr hWnd,
    [In] uint Msg,
    [In] ulong wParam,
    [In] long lParam
);

在上面的示例中,第一个实例使用IntPtr和UIntPtr(平台特定)类型,而第二个实例使用long和ulong,在x64上运行的“以防万一”和与指针大小相同的
INT\u PTR
。因此,它们在32位目标中的宽度为32位,在64位目标中的宽度为64位。在C语言中,使用
int
long
都是错误的,因为它们的大小是固定的。
INT_PTR
LONG_PTR
到C的正确翻译为
IntPtr


同样,对于未签名的变体,使用
uintpttr

您试图解决什么问题?PInvoke与这个问题有什么关系?@AlexFarber-见Remarksagin,还不清楚
IntPtr
具有正确的32位和64位大小。PInvoke调用的本机Dll具有相同的位,因此IntPtr与void*大小相同*@AlexFarber因此说我想PInvoke使用INT_PTR;使用实现是否特定(我需要根据实现选择正确的.NET数据类型,而不是通常使用IntPtr vs Int32/Int64)?不能从64位进程中PInvoke 32位Dll,从32位进程中PInvoke 64位Dll。因此,如果您使用参数INT#PTR来PInvoke原生Dll,将其声明为IntPtr,两者的大小将是相同的。问题…如何在C#中映射半#PTR(32位机器上为16位,64位机器上为32位)?这样的东西是否存在?!根据Windows数据类型参考,是。虽然它对我来说确实很奇怪——甚至可能不会在任何没有C#type可匹配的地方使用。我从来没见过这种类型有什么用。