我有一个本机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的工作正常(我可以将接收到的值发送消息),但是我尝试(至少)作为第三和第4个参数:
char* =>
=> string
=> StringBuilder
=> char[]
所有这些都用[In], [Out], [In,Out], out, ref
。
函数应更改PAR3和PAR4的值,并将整数返回回到调用应用程序。该应用程序读取PAR3的值(实际上是代表字符串的整数),并将其写入日志文件。检查日志文件后,该值不是funCname(...)。
中的一个集合。最常见的值是"(空),但是只有在将char[]
与out
或ref
一起使用时,似乎有一个值回传递,但它只是几个怪异的字符(不是在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 ";
byte[] outputBytes = Encoding.Default.GetBytes(outputStr);
Marshal.Copy(outputBytes, 0, par3, outputBytes.Length);
return 0;
}
请注意,我已经删除了unsafe
,因为不需要。