C# 正确使用DllImport 假设在nT.VDL中有一个C++方法 int NativeMethod(double,double *)。我第一次尝试从托管代码调用此方法是(假设我不需要指定入口点)

C# 正确使用DllImport 假设在nT.VDL中有一个C++方法 int NativeMethod(double,double *)。我第一次尝试从托管代码调用此方法是(假设我不需要指定入口点),c#,dll,pinvoke,marshalling,unmanaged,C#,Dll,Pinvoke,Marshalling,Unmanaged,然后使用我做的DLL IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); NativeMethod(2.0, x); //do stuff with x Marshal.FreeHGlobal(x); //crash 我想知道为什么会在这里崩溃。我的第一个猜测是,这是一个堆问题,因为DLL和我的应用程序可能使用不同的CRT。但是如果是这样,为什么对NativeMethod的调用不会崩溃呢?该方法返回一个x,我可

然后使用我做的DLL

IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
NativeMethod(2.0, x);

//do stuff with x

Marshal.FreeHGlobal(x);  //crash
我想知道为什么会在这里崩溃。我的第一个猜测是,这是一个堆问题,因为DLL和我的应用程序可能使用不同的CRT。但是如果是这样,为什么对NativeMethod的调用不会崩溃呢?该方法返回一个x,我可以成功地从中提取双精度

通过引用传递double,我可以使导入生效

[DllImport("Native.dll")]
private static extern int NativeMethod(double inD, IntPtr outD);

为什么FreeHGlobal在第一次尝试时会崩溃,推荐的将指针传递给本机方法的方法是什么?out关键字在这种情况下可能很好,但是如果我需要封送字符串呢?我不认为我能绕过阿洛奇和弗里…

我不是专家,但不应该是:

IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)));

问题是该方法采用了一个
double*
,它是指向double的指针。您正在传入一个指向
IntPtr
的指针。只有当
double
(8字节)和
IntPtr
之间存在大小差异时,这一点才很重要,因为后者的大小是可变的(4或8字节)。您需要将指针分配给一个
double

IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double));

我可能误解了你的目标,但你似乎把它弄得过于复杂了。只需通过引用传递它,并让下面的编组处理它

[DllImport("Native.dll")]
private static extern int NativeMethod(double inD, ref double outD);

double x;

x = 1;
NativeMethod( 2.0, ref x );

它给您的错误消息是什么?当然,这应该是typeof(double)。但是我认为SizeOf(typeof(InpPtr))总是>=SizeOf(typeof(double)),因此它可能以某种方式工作。有趣的是,什么是“用x做东西”部分?啊,非常感谢。。我错过了msdn参考中关于平台特定大小的部分。+1最有代表性的是使用out而不是ref。OP从未初始化指针。@JaredPar,这是真的。我不确定OP是想要ref还是out行为,但我没有意识到这一明显的线索(在示例中他没有初始化它的事实)。使用out/ref与AllocHGlobal访问无管理内存到底意味着什么?GC能否在方法/函数返回之前重新安排内存并更改指针引用?@thomask,有一个关于@thomask的讨论-关于它的另一点。我相信使用out/ref for将更有效。我认为简单变量的地址将直接传递给非托管DLL进行修改,因此它不涉及额外的分配。
[DllImport("Native.dll")]
private static extern int NativeMethod(double inD, ref double outD);

double x;

x = 1;
NativeMethod( 2.0, ref x );