导出托管C#函数以将更改的char*参数返回到非托管代码 我有一个本地C++(我想)应用程序,它可以被配置成加载某个DLL并调用一个函数。此函数返回int,接受四个参数,应至少更改其中一个参数并返回一个值。 根据手册,这个函数应该在C++中定义为: __declspec( dllexport ) int funcName(const char* par1, const char* par2, char* par3, char* par4);
但是,根据需要,此函数应在C#中实现。我使用非托管导出来允许我使用:导出托管C#函数以将更改的char*参数返回到非托管代码 我有一个本地C++(我想)应用程序,它可以被配置成加载某个DLL并调用一个函数。此函数返回int,接受四个参数,应至少更改其中一个参数并返回一个值。 根据手册,这个函数应该在C++中定义为: __declspec( dllexport ) int funcName(const char* par1, const char* par2, char* par3, char* par4);,c#,c++,.net,pinvoke,dllexport,C#,C++,.net,Pinvoke,Dllexport,但是,根据需要,此函数应在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 //
[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工作正常(我可以在messagebox中输入接收到的值),但是我尝试(至少)将以下参数作为第3和第4个参数:
char* =>
=> string
=> StringBuilder
=> char[]
所有这些都带有[In]、[Out]、[In、Out]、Out、ref
函数应该更改par3和par4的值,并将一个整数返回给调用应用程序。
应用程序读取par3的值(它实际上是一个用字符串表示的整数),并将其写入日志文件。检查日志文件后,该值不是funcName(…)中设置的值
最常见的值是“”(空),但是只有在将char[]
与out
或ref
一起使用时,才有一个值被传回,但它只是几个奇怪的字符(不是在funcName中设置的值)
所以问题是,当从非托管代码调用托管dll函数时,如何返回char*参数?我非常怀疑
非托管数据端口是否能为您完成这项工作。除非我大错特错,否则它不会使一个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;
}
请注意,我已删除了不安全的,
,因为这是不需要的。很抱歉,我完全误解了您的问题。我希望这次我做得更好。谢谢!为了得到这个答案,我已经研究了这么多不同的类似问题差不多一个星期了。我希望我现在有一个更大的声誉,这样我就可以投票支持这个解决方案,因为它是第一个有效的解决方案。再次感谢你!par3和par4字符指针是指向字符串还是接收单个字符的地址?您不需要设置字符集,否则它们将变成wchar\u t*
?@ta.speot.is否。默认值是ANSI。@ta.speot.is在CE上。默认值是Unicode,因为这就是全部内容。在其他任何地方,默认值都是Ansi
。当然,这里重要的是UnmanagedExports
的作用。因为这不是DllImport
。但我很确定Robert遵循了DllImport
@ta.speot.is FWIW的先例,您正在寻找的DllImport
参考资料如下: