2010-10-10 68 views
5

假设一个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更改为字节并手动将其从一个转换为另一个。所以,第一个问题是,有没有更好的方法来编组布尔(注意,这是布尔,而不是布尔)

第二个惊喜是,由dll函数返回的原始字符串是由C#字符串OWNED,不复制,正如我所料,最终C#代码释放了由dll返回的内存。我发现这是因为程序崩溃了,但后来我将返回类型更改为sbyte *并手动初始化该字符串,该字符串已经完成了该副本。所以第二个问题是:2.1:是否有更好的方法来防止编组字符串拥有指针。 2.2:跆拳道?为什么C#会这样做?我的意思是,一个明显的情况是,当DLL函数返回一个文字,并且C#试图删除它...

在此先感谢,并希望我的问题不是模糊或难以理解的。

回答

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(); 
5

默认情况下.NET自动封装在C++ BOOL(4字节)和.NET BOOL类型之间。对于C++布尔(单字节)输入您需要指定如何封送:

[DllImport("MyDll.dll")] 
internal static extern void f([MarshalAs(UnmanagedType.I1)] bool x); 
+0

@Darin:有趣的是,我的一个朋友告诉我同样的事情,你猜怎么着?它没有工作。我使用.Net1.1,如果这是相关的 – 2010-10-10 20:55:45

+1

其实这是从1.1支持。请参阅http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.unmanagedtype(v=VS.71).aspx – Vinzenz 2010-10-10 20:56:40

+0

@Armen它应该根据文档工作。 – 2010-10-10 20:58:35