c# - DllImport 的正确用法

标签 c# dll pinvoke marshalling unmanaged

假设在 Native.dll 中有一个 c++ 方法 int NativeMethod(double, double *)。我第一次尝试从托管代码调用此方法(假设我不需要指定入口点)

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

然后使用我做的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 值。

我可以通过引用传递 double 来使导入工作

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

为什么 FreeHGlobal 在第一次尝试时会崩溃,将指针传递给 native 方法的推荐方法是什么? out 关键字在这种情况下可能工作得很好,但是如果我需要编码(marshal)一个字符串怎么办?我不认为我可以绕过 AllocH 和 FreeH...

最佳答案

我可能误解了你的目标,但你似乎把它变得比必要的更复杂了。只需通过引用传递它,让下面的编码处理它。

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

double x;

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

关于c# - DllImport 的正确用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3238334/

相关文章:

c++ - 从另一个 dll 链接动态 dll 会导致错误

c# - 将结构体数组从 C# 编码到 VC++

c++ - 在全屏模式游戏中运行exe文件

c# - 如何仅使用 2 replace 替换完全匹配的字符串

c# - WebForms ASCX 中的 Linq Lambda 支持

c# - 第一次加载页面时,如何获取下拉列表的选定项?

java - 缺少 `server' JVM (Java\jre7\bin\server\jvm.dll。)

c# - 调试 winform 崩溃 - C# [ADPlus + Windbg]

c# - 从 C# 代码使用 C 库

c# - 将行添加到可编辑的 GridView 后,日期选择器未出现