c# - PInvoke 和 char**

标签 c# .net pinvoke char marshalling

我从某人那里得到了这个程序集,我想在我的 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);

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

我应该怎么做才能让它正常工作?

编辑:

好的,我设法开始工作,方法是将 char[] 替换为 IntPtr,然后像 Nick 建议的那样调用“Marshal.PtrToStringAnsi”:

string result = Marshal.PtrToStringAnsi(ptr);

但是,由于同一答案中的评论,我有点担心内存使用情况。程序集中没有提供其他方法,那么我该如何清理呢?

最佳答案

关于你的最后一个问题:

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

关于c# - PInvoke 和 char**,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5975380/

相关文章:

c# - 删除按钮 - 无效的回发或回调参数

c# - 与存储过程一起使用时,Linq to SQL 是否快速?

c# - ASP.NET ListView 填充

C# - 用于循环 DataGridView.Rows 的 Lambda 语法

c# - 实现 Win32 消息循环并使用 P/Invoke 创建 Window 对象

c# - 针对列截断数据,但截断的数据是空的 C#/MySql

c# - C# 中的父子流畅 Linq 查询?

.net - 如何折叠段落?

c# - 如何判断默认打印机何时更改?

string - 如何 PInvoke 多字节 ANSI 字符串?