
[英]Calling a unmanaged C method with a const char** argument from managed C# code
[英]Export managed C# function to return changed char* parameter to unmanaged code
我有一个本地C ++(我认为)应用程序,可以将其配置为加载某个dll并调用一个函数。 此函数返回int,接受四个参数,应更改两个参数中的至少一个并返回一个值。 根据手册,此功能应在C ++中定义为:
__declspec( dllexport ) int funcName(const char* par1, const char* par2, char* par3, char* par4);
但是,根据需要,此功能应在C#中实现。 我正在使用“不受管理的导出”来允许我使用:
[DllExport("funcName", CallingConvention.Cdecl)]
public static unsafe int funcName(string par1, string par2, string par3, string par4) {
// sample for par3 only when using StringBuilder instead of string
// but is similar with other types
par3 = new StringBuilder(256);
par3.Append("12345");
return 0;
}
参数1和2可以正常工作(我可以在消息框中输入接收到的值),但是我已经尝试(至少)将以下参数用作第3和第4个参数:
char* =>
=> string
=> StringBuilder
=> char[]
所有这些都带有[In], [Out], [In,Out], out, ref
。
函数应更改par3和par4的值,并将整数返回给调用应用程序。 应用程序读取par3的值(它实际上是一个表示为字符串的整数),并将其写到日志文件中。 检查日志文件后,该值不是funcName(...)中设置的值。
最通常的值是“”(空),但是仅当使用带out
或ref
char[]
时out
似乎才传回了一个值,但这只是一些奇怪的chars(不是funcName中设置的值)。
因此问题是,从非托管代码调用托管dll函数时如何返回char *参数?
我非常怀疑UnmanagedImports
将为您完成这项工作。 除非我非常误解,否则它不会使StringBuilder
成为现实。 我认为您需要这样编码:
[DllExport("funcName", CallingConvention.Cdecl)]
public static int funcName(string par1, string par2, IntPtr par3, IntPtr par4)
{
string inputStr = Marshal.PtrToStringAnsi(par3);
string outputStr = "foo\0";
byte[] outputBytes = Encoding.Default.GetBytes(outputStr);
Marshal.Copy(outputBytes, 0, par3, outputBytes.Length);
return 0;
}
请注意,我已删除了unsafe
因为这是不必要的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.