- 我没有完全访问 DLL 源的权限,只有标题。
- 我的实际代码中的参数名称更具描述性
我正在尝试调用一个接受所有 char * 变量的非托管 DLL,其中两个充当“返回”值。in1-8 是输入,in9 和 10 是长度为 512 的 char *,并传入空。调用完成后,应该用结果数据填充它们。
这是我正在尝试使用的示例定义:
[DllImport("mydll.dll")]
public static extern IntPtr foo(
IntPtr in1,
IntPtr in2,
IntPtr in3,
IntPtr in4,
IntPtr in5,
IntPtr in6,
IntPtr in7,
IntPtr in8,
ref IntPtr result1,
ref IntPtr result2);
这是我的电话:
IntPtr param1 = Marshal.StringToHGlobalUni("testdata");
IntPtr param2 = Marshal.StringToHGlobalUni("testdata");
IntPtr param3 = Marshal.StringToHGlobalUni("testdata");
IntPtr param4 = Marshal.StringToHGlobalUni("testdata");
IntPtr param5 = Marshal.StringToHGlobalUni("testdata");
IntPtr param6 = Marshal.StringToHGlobalUni("testdata");
IntPtr param7 = Marshal.StringToHGlobalUni("testdata");
IntPtr param8 = Marshal.StringToHGlobalUni("testdata");
IntPtr param9 = IntPtr.Zero;
IntPtr param10 = IntPtr.Zero;
foo(param1, param2, param3, param4, param5, param6, param7, param8, ref param9, ref param10);
要打印 IntPtr,我正在做:
string str = Marshal.PtrToStringUni(param9);
Console.WriteLine(str);
在给我的“示例”中,C++ 调用如下所示:
char result1[512]="";
char result2[512]="";
foo("testdata", "testdata", "testdata", "testdata", "testdata", "testdata", "testdata", "testdata", result1, result2);
printf("%s,%s\n",result1,result2);
问题:在我尝试过的所有方式中,包括将 char[512] 转换为 byte[]、StringBuilder 大小为 512、IntPtr 等。每次返回时,param9 和 param10 值都是空的。谁能帮我解决这个问题?提前致谢。
编辑 在下面的一些有用的评论和更多的谷歌搜索之后,我修补了我凌乱的代码来工作。这是编辑:
[DllImport("mydll.dll")]
public static extern IntPtr foo(
IntPtr in1,
IntPtr in2,
IntPtr in3,
IntPtr in4,
IntPtr in5,
IntPtr in6,
IntPtr in7,
IntPtr in8,
IntPtr result1,
IntPtr result2);
我摆脱了两个结果字符数组的 ref。
IntPtr param1 = Marshal.StringToHGlobalAnsi("testdata");
IntPtr param2 = Marshal.StringToHGlobalAnsi("testdata");
IntPtr param3 = Marshal.StringToHGlobalAnsi("testdata");
IntPtr param4 = Marshal.StringToHGlobalAnsi("testdata");
IntPtr param5 = Marshal.StringToHGlobalAnsi("testdata");
IntPtr param6 = Marshal.StringToHGlobalAnsi("testdata");
IntPtr param7 = Marshal.StringToHGlobalAnsi("testdata");
IntPtr param8 = Marshal.StringToHGlobalAnsi("testdata");
IntPtr param9 = Marshal.AllocHGlobal(512 * sizeof(int));
IntPtr param10 = Marshal.AllocHGlobal(512 * sizeof(int));
foo(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10);
上面我分配了 param9 和 10 而不是 IntPtr.Zero
//printing..
string str = Marshal.PtrToStringAnsi(param9);
由于以下答案,使用字符串也是一种更简单的方法:
[DllImport("mydll.dll")]
public static extern IntPtr foo(
string in1,
string in2,
string in3,
string in4,
string in5,
string in6,
string in7,
string in8,
StringBuilder result1,
StringBuilder result2);
然后:
StringBuilder resultA = new StringBuilder(512);
StringBuilder resultB = new StringBuilder(512);
foo("test", "test", "test", "test", "test", "test", "test", "test", resultA, resultB);
印刷:
Console.WriteLine(resultA.ToString());
现在看起来好多了,现在实际工作了,谢谢大家!打开 50 个谷歌搜索标签很容易混淆。