【发布时间】:2008-10-02 15:12:59
【问题描述】:
给定 DLL 中的以下 C 函数:
char * GetDir(char* path );
您将如何将此函数 P/Invoke 到 C# 中并正确编组 char *。 .NET 似乎知道如何执行 LPCTSTR,但是当我无法弄清楚在调用此函数时不会导致 NotSupportedException 触发的任何封送处理时。
【问题讨论】:
标签: .net pinvoke marshalling
给定 DLL 中的以下 C 函数:
char * GetDir(char* path );
您将如何将此函数 P/Invoke 到 C# 中并正确编组 char *。 .NET 似乎知道如何执行 LPCTSTR,但是当我无法弄清楚在调用此函数时不会导致 NotSupportedException 触发的任何封送处理时。
【问题讨论】:
标签: .net pinvoke marshalling
OregonGhost 的答案只有在从 GetDir 返回的 char* 分配到 HGlobal 或 LocalAlloc 时才是正确的。我不记得是哪一个,但 CLR 会假定来自 PInvoke 函数的任何字符串返回类型都分配有一个或另一个。
一种更稳健的方法是将 GetDir 的返回值键入为 IntPtr。然后,您可以使用任何 Marshal.PtrToStringAnsi 函数来获取字符串类型。它还为您提供了以您选择的方式释放字符串的灵活性。
[DllImport("your.dll", CharSet = CharSet.Ansi)]
IntPtr GetDir(StringBuilder path);
您能否就 GetDir 的行为给我们任何其他提示?它会修改输入字符串吗?返回的值是如何分配的?如果你能提供,我可以给出更好的答案。
【讨论】:
试试
[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 会失败吗?