带有void*的PInvoke与带有IntPtr的结构

hal*_*ton 6 c# pinvoke interop

想象一下,我有一个叫做的函数

Myfunction(const void * x);
Run Code Online (Sandbox Code Playgroud)

我的C#声明可能是

MyFunction(IntPtr x);
Run Code Online (Sandbox Code Playgroud)

这在功能和技术上是等同于

struct MyStruct { IntPtr P; }

MyFunction(MyStruct x);
Run Code Online (Sandbox Code Playgroud)

或者他们的编组方式会有所不同.

我问这个是因为我正在调用的库是无效*,对其他名称键入了类型,而在C#中我希望获得类型安全性,因为它的价值.

小智 3

如果你的 StructLayout 是 Sequential 的,那么它确实是相同的。

当然,亲自验证这一点的最简单方法就是尝试一下:

制作一个 C++ Win32 DLL 项目:

extern "C"
{
    __declspec(dllexport) void MyFunction(const void* ptr)
    {
       // put a breakpoint and inspect
    }
}
Run Code Online (Sandbox Code Playgroud)

制作一个 C# 项目:

    public struct Foo
    {
        public IntPtr x;
    }

    [DllImport(@"Win32Project1.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl)]
    public static extern void MyFunctionWithIntPtr(IntPtr x);

    [DllImport(@"Win32Project1.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl)]
    public static extern void MyFunctionWithStruct(Foo x);

    static void Main(string[] args)
    {
        IntPtr j = new IntPtr(10);
        var s = new Foo();
        s.x = new IntPtr(10);
        MyFunctionWithIntPtr(j);
        MyFunctionWithStruct(s);
    }
Run Code Online (Sandbox Code Playgroud)

在调试设置中,确保选择启用本机调试。

您将看到两个值都是 0xA。

但请注意,如果您对 IntPtr 与 Struct 使用 out/ref 参数,它们将是不同的值。

  • 反复试验并不能证明什么。你怎么知道另一个例子的行为没有不同? (2认同)