C# 从C+返回长度未知的字符串+;从C调用#

C# 从C+返回长度未知的字符串+;从C调用#,c#,c++,.net,string,parameter-passing,C#,C++,.net,String,Parameter Passing,我已经到处寻找我问题的答案,所有的解决方案都是不可接受、不适用和/或令人困惑的 我需要将一个字符串从C++中实现的函数返回到C#中的调用代码 返回的字符串需要作为参数而不是返回值返回,因为我需要为某些函数传递/返回多个字符串。字符串的长度不同,所以我不能只分配一个缓冲区,等等 任何帮助都将不胜感激 注意:Justin和/或其他人发布和提及的解决方案不是我的用例的解决方案。正如我在这个问题中所说的,在调用C++代码之前,我不知道字符串的大小。我不能预先分配StringBuffer并将其传递给C++

我已经到处寻找我问题的答案,所有的解决方案都是不可接受、不适用和/或令人困惑的

我需要将一个字符串从
C++
中实现的函数返回到
C#
中的调用代码

返回的字符串需要作为参数而不是返回值返回,因为我需要为某些函数传递/返回多个字符串。字符串的长度不同,所以我不能只分配一个缓冲区,等等

任何帮助都将不胜感激


注意:Justin和/或其他人发布和提及的解决方案不是我的用例的解决方案。正如我在这个问题中所说的,在调用C++代码之前,我不知道字符串的大小。我不能预先分配StringBuffer并将其传递给C++代码。<强> >/p> < P>一种方法是将参数声明为“代码> REF ItPTR。因此:

static extern void DoSomething(ref IntPtr returnedString);
所以你调用它并得到一个字符串:

IntPtr pstr;
DoSomething(ref pstr);
string theString = Marshal.PtrToStringAnsi(pstr);
<>但是,记住返回的指针是由C++代码分配的很重要。如果你想让它被释放,你需要调用C++代码来完成它。 您可能还需要查看
封送处理.PtrToStringAuto
,以及其他类似的函数


还要注意,这会将数据从指针复制到字符串。如果您想在适当的位置引用字符串,您必须使用
IntPtr
Marshal
类,或者深入研究不安全代码和指针的奇妙世界。

除了Jim Michel的答案之外,我还创建了一个助手函数,如

String FromCppString(IntPtr a_Pointer)
{
    String result = Marshal.PtrToStringAnsi(a_Pointer);
    FreeCppString(a_Pointer);
    return result;
}
<> >代码> FReCPPsstring 是从C++导出的另一个函数,正确释放字符串。原始C++函数将根据需要分配尽可能多的字符串并将它们放入参数中。C#函数将使用FromCppString()来提取它们。

使用平台提供的可移植(多编译器多语言)字符串,以便在以不同语言实现的组件之间传递字符串--
BSTR

<>在C++中,你使用<代码> SysLoScRoS< /COD>或<代码> SysLoSrrutLIN < /C>。P/invoke已经知道如何处理这些(转换为.NET字符串并调用
SysFreeString
),只要您使用正确的签名

extern static void DoSomething([MarshalAs(UnmanagedType.BStr)] out String returnedString);
然后简单地称之为:

string theString;
DoSomething(out theString);
就是这样,不需要特殊的转换或清理,因为p/invoke处理了它

有关更多信息,请阅读

注:我猜链接中的例子没有一个完全是这个例子,所以C++原型< /p>
void DoSomething(__out BSTR *s);

请添加函数声明。托管C++或本机C++?参见。分配字符串的内存在哪里?通过调用方或被调用方贾斯廷,接受的答案涉及预先分配缓冲区,我说这是不可能的,因为我不知道调用C++缓冲区之前需要的大小。<代码> M.SHAL.PttotoStRangnsi是很好的,如果您必须与二进制BLB通信。如果你能控制双方,那就永远不是一个好的选择。@BenVoigt:明白。从Q,我觉得他没有控制。C++原型看起来像什么?是:void DoSomething(int*returnedString)?C++代码是原生的,不是托管的。@ StPiSoSoLe: C++原型将是<代码>无效DoSomething(char * ReurndStand);<代码>或者,如果返回Unicode字符串:
TCHAR*returnedString)类似于:std::string str=“敏捷的棕色狐狸跳过了懒狗”;returnedString=新字符[str.length()+1];str.copy(returnedString,str.length()-1,0);C++原型是什么样子的?是:void DoSomething(char**returnedString)?C++代码是原生的。@ Stephenosella:<代码> SysLoSoScxs> /Cord>和 SysFristSoG是当代码< >包含< /C> >时使用的本机函数。您可以使用Unicode,或者
SysAllocStringByteLen
[MarshalAs(UnmanagedType.AnsiBStr)]