.net C#中的元帅“char *”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/162897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Marshal "char *" in C#
提问by Adam Haile
Given the following C function in a DLL:
给定 DLL 中的以下 C 函数:
char * GetDir(char* path );
How would you P/Invoke this function into C# and marshal the char * properly. .NET seems to know how to do LPCTSTR but when I can't figure out any marshaling that doesn't cause a NotSupportedException to fire when calling this function.
您将如何将此函数 P/Invoke 到 C# 并正确编组 char *。.NET 似乎知道如何执行 LPCTSTR,但是当我无法找出在调用此函数时不会导致 NotSupportedException 触发的任何封送处理时。
回答by JaredPar
OregonGhost's answer is only correct if the char* returned from GetDir is either allocated in HGlobal or LocalAlloc. I can't remember which one but the CLR will assume that any string return type from a PInvoke function was allocated with one or the other.
如果从 GetDir 返回的 char* 分配在 HGlobal 或 LocalAlloc 中,OregonGhost 的答案才是正确的。我不记得是哪一个,但 CLR 会假设来自 PInvoke 函数的任何字符串返回类型都分配了一个或另一个。
A more robust way is to type the return of GetDir to be IntPtr. Then you can use any of the Marshal.PtrToStringAnsi functions in order to get out a string type. It also gives you th flexibility of freeing the string in the manner of your choosing.
更可靠的方法是将 GetDir 的返回类型输入为 IntPtr。然后您可以使用任何 Marshal.PtrToStringAnsi 函数来获取字符串类型。它还为您提供了以您选择的方式释放字符串的灵活性。
[DllImport("your.dll", CharSet = CharSet.Ansi)]
IntPtr GetDir(StringBuilder path);
Can you give us any other hints as to the behavior of GetDir? Does it modify the input string? How is the value which is returned allocated? If you can provide that I can give a much better answer.
您能否就 GetDir 的行为给我们任何其他提示?它会修改输入字符串吗?返回的值是如何分配的?如果你能提供,我可以给出更好的答案。
回答by OregonGhost
Try
尝试
[DllImport("your.dll", CharSet = CharSet.Ansi)]
string GetDir(StringBuilder path);
string is automatically marshalled to a zero-terminated string, and with the CharSet property, you tell the Marshaller that it should use ANSI rather than Unicode. Note: Use string (or System.String) for a const char*, but StringBuilder for a char*.
字符串会自动编组为以零结尾的字符串,并使用 CharSet 属性告诉编组器它应该使用 ANSI 而不是 Unicode。注意:对 const char* 使用 string(或 System.String),对 char* 使用 StringBuilder。
You can also try MarshalAs, as in this example.
您也可以尝试 MarshalAs,如本例所示。

