C# 平沃克和查尔**
我想在我的c#应用程序中使用某个人提供的程序集 标题如下所示:C# 平沃克和查尔**,c#,.net,pinvoke,char,marshalling,C#,.net,Pinvoke,Char,Marshalling,我想在我的c#应用程序中使用某个人提供的程序集 标题如下所示: int __declspec(dllimport) s2o(WCHAR* filename, char** out, int* len); char[] result = null; int length = 0; s2o("filepath", ref result, ref length); 我设法使它部分工作,使用: [DllImport("s2o.dll", EntryPoint = "?skn2obj@@YAHPA_W
int __declspec(dllimport) s2o(WCHAR* filename, char** out, int* len);
char[] result = null;
int length = 0;
s2o("filepath", ref result, ref length);
我设法使它部分工作,使用:
[DllImport("s2o.dll", EntryPoint = "?skn2obj@@YAHPA_WPAPADPAH@Z", CallingConvention = CallingConvention.Cdecl)]
public static extern int s2o(
[MarshalAs(UnmanagedType.LPWStr)]
string filename,
ref char[] @out,
ref int len
);
然后这样称呼它:
int __declspec(dllimport) s2o(WCHAR* filename, char** out, int* len);
char[] result = null;
int length = 0;
s2o("filepath", ref result, ref length);
它似乎部分起作用,因为“length”实际上得到了一个值。
不幸的是,“result”保持为空
我该怎么做才能让它工作
编辑:
好的,我用IntPtr替换了char[],然后调用'Marshal.PtrToStringAnsi'开始工作,就像Nick建议的那样:
string result = Marshal.PtrToStringAnsi(ptr);
然而,由于同一答案中的注释,我有点担心内存使用。程序集中没有提供其他方法,因此我如何才能澄清问题?关于您的最后一个问题:
是单个字符李>char
是指向字符的指针。如果这被解释为一个字符串,那么内存地址后面的所有数据都将被视为属于该字符串,直到遇到一个0x0的值为止。将char*
传递给方法意味着该方法可以更改字符串的内容,但不能更改其长度李>char*
是指向char的指针。将其传递给方法意味着该方法能够创建新字符串并将新地址返回给调用方char**
还请注意,您可能负责释放此函数返回的内存。您可以尝试用IntPtr替换char[],并为指针调用PtrToStringAuto:Marshal.PtrToStringAuto(@out)请在DLL中用extern“C”声明您的函数以禁用名称篡改。现在谈谈你的问题。在您告诉我们
out
参数如何工作之前,我们无法告诉您如何调用此函数。谁分配什么?你有关于s2o
的文档吗?@David:我想他是说这是一个第三方DLL,所以他可能无法添加外部“C”。它确实是一个第三方DLL。你可以尝试使用Marshal.FreeCoTaskMem或FreeHGlobal。但是如果不知道DLL中内存是如何分配的,就很难知道会发生什么!托管代码如何释放本机代码中分配的内存?只有当本机代码提供了释放它的方法、导出了分配器或使用了COM分配器时,这才有效。@David:是的,你说得对。O.P.将需要查看DLL的文档,并计算出预期如何释放内存。虽然PtrToStringAuto工作,但我没有得到预期的结果(相反,我得到了很多中文字符),因此我认为出现了一些问题。另外,我很确定'out'是一个字符数组,所以我不需要先做一些转换吗?你试过Ansi版本吗?另一种可能性是,char**
是一个C字符串数组,例如argv
。