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

时间:2015-02-12 00:55:16

标签: c# interop pinvoke

想象一下,我有一个名为

的函数
Myfunction(const void * x);

我的C#声明可能是

MyFunction(IntPtr x);

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

struct MyStruct { IntPtr P; }

MyFunction(MyStruct x);

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

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

1 个答案:

答案 0 :(得分:3)

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

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

制作C ++ Win32 DLL项目:

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

制作一个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);
    }

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

您会看到这两个值都是0xA。

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