PInvoke 和 char**

发布于 2024-11-07 02:04:52 字数 884 浏览 5 评论 0原文

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

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

I got this assembly from someone which I'd like to use in my c# application.

The header looks like this:

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

I managed to get it partly working, using:

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

And then calling it like this:

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

It seems to work partly, because 'length' actually gets a value.
Unfortunatly, 'result' stays null.

What should I do to get this working?

Edit:

Ok I managed to get to to work by replacing the char[] with a IntPtr and then calling 'Marshal.PtrToStringAnsi' like Nick suggested:

string result = Marshal.PtrToStringAnsi(ptr);

However, because of the comments in that same answer I'm a little worried about memory usage. There are no other methods provided in the assembly so how can I clear things up?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

宫墨修音 2024-11-14 02:04:52

关于你的最后一个问题:

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

About your last question:

  • char is a single character.
  • char* is a pointer to a char. If this is interpreted as a string, all data in the memory that follow this memory address will be seen as belonging to the string, up until a value with 0x0 is encountered. Passing a char* into a method means, that this method can change the contents of the string, but not its length.
  • char** is a pointer to a pointer to a char. Passing this to a method means that the method is able to create a new string and return the new address to the caller.
我乃一代侩神 2024-11-14 02:04:52

查看 Marshal.PtrToStringAnsi 方法。

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

复制所有字符到第一个字符
来自非托管 ANSI 的空字符
string 为托管 String,并加宽
每个 ANSI 字符到 Unicode。

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

Have a look at the Marshal.PtrToStringAnsi Method.

Or as Centro says in the comment to your question, PtrToStringAuto may be more appropriate.

Copies all characters up to the first
null character from an unmanaged ANSI
string to a managed String, and widens
each ANSI character to Unicode.

Also note that you may be responsible for freeing the memory returned from this function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文