假设一个dll包含以下函数
extern "C" __declspec(dllexport) void f(bool x)
{
//do something
}
extern "C" __declspec(dllexport) const char* g()
{
//do something else
}
我在C#中使用这些函数的第一个天真的方法如下:
[DllImport("MyDll.dll")]
internal static extern void f(bool x);
[DllImport("MyDll.dll")]
internal static extern string g();
第一个惊喜是C ++ bool没有转换成C#bool(奇怪的运行时行为,但没有崩溃)。所以我不得不将bool更改为byte并手动将其从一个转换为另一个。所以,第一个问题是,有没有更好的方法来编组bool(注意这是bool,而不是BOOL)
第二个惊喜是dll函数返回的原始字符串是C#字符串的OWNED,没有像我期望的那样复制,最终C#代码释放了dll返回的内存。我找到了这个,因为程序崩溃,但后来我将返回类型更改为sbyte *并使用已经执行复制的指针手动初始化字符串。所以第二个问题是:2.1:有没有更好的方法来阻止编组的字符串拥有指针。 2.2:WTF?!为什么C#会这样做?我的意思是,一个明显的例子是当dll func返回一个文字时,C#试图删除它......
提前致谢,希望我的问题不含糊或不可理解。
答案 0 :(得分:5)
默认情况下,.NET会自动在C ++ BOOL(4字节)和.NET bool类型之间进行编组。对于C ++ bool(单字节)类型,您需要指定如何编组:
[DllImport("MyDll.dll")]
internal static extern void f([MarshalAs(UnmanagedType.I1)] bool x);
答案 1 :(得分:5)
[DllImport("MyDll.dll")]
internal static extern void f( [MarshalAs(UnmanagedType.I1)] bool x );
[DllImport("MyDll.dll")]
[return: MarshalAs(UnmanagedType.LPStr)]
internal static extern string g();