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);
会成功,但返回string
和CharSet = CharSet.Ansi
会失败吗?以上是关于C# 中的元帅“char *”的主要内容,如果未能解决你的问题,请参考以下文章