C# 中的元帅“char *”

Posted

技术标签:

【中文标题】C# 中的元帅“char *”【英文标题】:Marshal "char *" in C# 【发布时间】:2008-10-02 15:12:59 【问题描述】:

给定 DLL 中的以下 C 函数:

char * GetDir(char* path );

您将如何将此函数 P/Invoke 到 C# 中并正确编组 char *。 .NET 似乎知道如何执行 LPCTSTR,但是当我无法弄清楚在调用此函数时不会导致 NotSupportedException 触发的任何封送处理时。

【问题讨论】:

【参考方案1】:

OregonGhost 的答案只有在从 GetDir 返回的 char* 分配到 HGlobal 或 LocalAlloc 时才是正确的。我不记得是哪一个,但 CLR 会假定来自 PInvoke 函数的任何字符串返回类型都分配有一个或另一个。

一种更稳健的方法是将 GetDir 的返回值键入为 IntPtr。然后,您可以使用任何 Marshal.PtrToStringAnsi 函数来获取字符串类型。它还为您提供了以您选择的方式释放字符串的灵活性。


[DllImport("your.dll", CharSet = CharSet.Ansi)]
IntPtr GetDir(StringBuilder path);

您能否就 GetDir 的行为给我们任何其他提示?它会修改输入字符串吗?返回的值是如何分配的?如果你能提供,我可以给出更好的答案。

【讨论】:

Ahhhh.... PtrToStringAnsi 正是我一直在寻找的东西,同时我已经想出使用 IntPtr,但现在我遇到了一个障碍...我正在使用 .NETCF并且 PtrToStringAnsi 仅在完整框架中:( 原来 OpenNetCF 有 PtrToStringAnsi....看起来问题已经解决了。一旦我可以测试代码,就会将此标记为已接受。 .NET 是否自动知道将 StringBuilder 编组为 char * 用于输入参数,或者是否需要一些第三方库才能使其工作?谢谢。【参考方案2】:

试试

[DllImport("your.dll", CharSet = CharSet.Ansi)]
string GetDir(StringBuilder path);

string 会自动编组为以零结尾的字符串,并且使用 CharSet 属性,您可以告诉 Marshaller 它应该使用 ANSI 而不是 Unicode。 注意:对 const char* 使用 string(或 System.String),对 char* 使用 StringBuilder。

你也可以试试 MarshalAs,比如this example。

【讨论】:

您知道为什么string ansi = Marshal.PtrToStringAnsi(ptr); 会成功,但返回stringCharSet = CharSet.Ansi 会失败吗?

以上是关于C# 中的元帅“char *”的主要内容,如果未能解决你的问题,请参考以下文章

c# 中的元帅 char[][LENGTH]

从 c# 到 c++ 的结构中的元帅结构

VS2010中的元帅结构指针

元帅浮点*到 C#

具有对 C# 的整数引用的元帅结构

在 C# 中元帅 C++ wchar_t**