PInvoke和char **

我从我想在c#应用程序中使用的人那里得到了这个程序集。

标题看起来像这样:

int __declspec(dllimport) s2o(WCHAR* filename, char** out, int* len); 

我设法让它部分工作,使用:

 [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 ); 

然后像这样调用它:

 char[] result = null; int length = 0; s2o("filepath", ref result, ref length); 

它似乎部分起作用,因为“长度”实际上得到了一个值。 不幸的是,’结果’保持为空。

我应该怎么做才能使这个工作?

编辑:

好吧,我设法通过用IntPtr替换char []然后像Nick建议调用’Marshal.PtrToStringAnsi’来工作:

 string result = Marshal.PtrToStringAnsi(ptr); 

但是,由于同一回答中的评论,我有点担心内存使用情况。 assembly中没有提供其他方法,所以如何清理?

看看Marshal.PtrToStringAnsi方法。

或者正如Centro在您的问题的评论中所说,PtrToStringAuto可能更合适。

将所有字符从非托管ANSI字符串复制到第一个空字符到托管字符串,并将每个ANSI字符扩展为Unicode。

另请注意,您可能负责释放此函数返回的内存。

关于你的上一个问题:

  • char是一个单个字符。
  • char*是一个指向char的指针。 如果将其解释为字符串,则内存中跟随此内存地址的所有数据将被视为属于字符串,直到遇到具有0x0的值。 将char*传递给方法意味着,此方法可以更改字符串的内容,但不能更改其长度。
  • char**是指向char**的指针。 将此传递给方法意味着该方法能够创建新字符串并将新地址返回给调用者。