ayj*_*jis 3 .net c# unmanaged marshalling dllimport
嘿伙计们,我正在尝试调用一个非托管DLL,它接受所有char*变量,其中两个充当"返回"值.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);
Run Code Online (Sandbox Code Playgroud)
这是我的电话:
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);
Run Code Online (Sandbox Code Playgroud)
要打印IntPtr,我正在做:
string str = Marshal.PtrToStringUni(param9);
Console.WriteLine(str);
Run Code Online (Sandbox Code Playgroud)
在给我的"示例"中,C++调用如下所示:
char result1[512]="";
char result2[512]="";
foo("testdata", "testdata", "testdata", "testdata", "testdata", "testdata", "testdata", "testdata", result1, result2);
printf("%s,%s\n",result1,result2);
Run Code Online (Sandbox Code Playgroud)
问题:我尝试的各种方式,包括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);
Run Code Online (Sandbox Code Playgroud)
我摆脱了两个结果char数组的引用.
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);
Run Code Online (Sandbox Code Playgroud)
上面我分配了param9和10而不是IntPtr.Zero
//printing..
string str = Marshal.PtrToStringAnsi(param9);
Run Code Online (Sandbox Code Playgroud)
使用字符串也是一种更简单的方法,感谢下面的答案:
[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);
Run Code Online (Sandbox Code Playgroud)
然后:
StringBuilder resultA = new StringBuilder(512);
StringBuilder resultB = new StringBuilder(512);
foo("test", "test", "test", "test", "test", "test", "test", "test", resultA, resultB);
Run Code Online (Sandbox Code Playgroud)
打印:
Console.WriteLine(resultA.ToString());
Run Code Online (Sandbox Code Playgroud)
它看起来好多了,现在实际上有效,谢谢你们!很容易混淆50个谷歌搜索标签打开.
假设您有以下c声明
extern "C" __declspec(dllexport) {
void foo(char * input, char * output);
}
Run Code Online (Sandbox Code Playgroud)
我将定义以下C#定义:
[DllImport("mydll.dll", EntryPoint="foo")]
public static extern void Foo(string input, StringBuilder output);
Run Code Online (Sandbox Code Playgroud)
并且呼叫将是这样的:
string input = "input";
var output = new StringBuilder(512);
Foo(input, output);
Run Code Online (Sandbox Code Playgroud)
如果可能,尽量避免使用不安全的代码.
| 归档时间: |
|
| 查看次数: |
4629 次 |
| 最近记录: |