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);
但是,由于同一答案中的评论,我'我有点担心内存使用情况。程序集中没有提供其他方法,那么我该如何清理呢?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关于你的最后一个问题:
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 achar*
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.查看 Marshal.PtrToStringAnsi 方法。
或者正如 Centro 在对您的问题的评论中所说,PtrToStringAuto 可能更合适。
另请注意,您可能负责释放从此函数返回的内存。
Have a look at the Marshal.PtrToStringAnsi Method.
Or as Centro says in the comment to your question, PtrToStringAuto may be more appropriate.
Also note that you may be responsible for freeing the memory returned from this function.