C# C++/CLR 处理 ref 参数和字符串指针
Posted
技术标签:
【中文标题】C# C++/CLR 处理 ref 参数和字符串指针【英文标题】:C# C++/CLR handling ref parameters and string pointers 【发布时间】:2018-02-27 12:51:11 【问题描述】:我正在为我的 C# 应用程序使用 C++/CLR DLL,并且一直在努力将 byRef 参数传递给本机方法,因为本机代码带有“&”,但 C# 提示我需要删除“ref”(或“out”)关键字。 此外,参数在我的 C# 和字符串中转换为“”,例如无法接受该类型,因此我收到从“字符串”到“字符串”的转换错误。
我在这个演示中使用 Pavel Yosifovich 示例代码:
托管 C++ 文件:ManagedPerson.cpp
String^ ManagedPerson::SayHello(String^ &greet)
marshal_context ctx;
return gcnew String(m_pNative->SayHello(ctx.marshal_as<LPCTSTR>(greet)));
我的 C# 应用:Main.cs
static void Main(string[] args)
var person = new ManagedPerson("Bart", 10);
Console.WriteLine(person.SayHello("Hello "));
然后我在 C# 编译中遇到此错误(由 person.SayHello 引起):
Argument 1: cannot convert from 'string' to 'string*'
如果我从 C++ 代码 (String^ &greet) 中删除“&”,这将有效,但我必须通过引用发送它。
我已经成功地使用 IntPtr 来使用像 Int32 这样的类型(尽管作为不安全的代码),但问题在于字符串和其他复杂类型。
任何线索都会有所帮助。谢谢。
【问题讨论】:
这个答案可能有帮助吗? link 您试图在错误的位置处理互操作。 C++\CLR 和 C# 使用相同的语言,所以在 C++\CLR 方法中去掉“&”。非托管的SayHello
成员函数是什么样的?
谢谢。 SayHello 在示例中如下所示: CString NativePerson::SayHello(LPCTSTR greet) return greet + m_Name;在我的应用程序中,我使用 std::wstring 而不是 CString 和 LPCTSTR
当从 String^ ManagedPerson::SayHello(String^ &greet) 中删除“&”时它有效,但我没有得到对我发送的值的引用...
好吧,样本无关紧要。 编辑您的问题以包含 NativePerson 类定义和 ManagedPerson 类的其余部分。没有足够的信息来说明这里发生了什么。
【参考方案1】:
好的,这样就解决了:
当我在 C++ 代码中的字符串引用参数类似于 Foo(String^ MyStr) 时,我的 CLR 期望它为字符串*。
我必须像 String^% 一样调用它才能在常规 Foo(ref string MyStr) 中调用它
但是,MANAGED 类不会将值传递给 ref 参数,所以我不得不使用临时参数,即:
Void Foo(String^ %MyStr)
marshal_context ctx;
std::wstring temp_MyStr = ctx.marshal_as<std::wstring>(MyStr);
myCppClass->DoSomthing(temp_MyStr);
MyStr = temp_MyStr.c_str();
这也指其他类型,例如 int%、short% 等。
对于问题中的示例,解决方案只是将“&”替换为“%”。
String^ ManagedPerson::SayHello(String^ %greet)
希望这会有所帮助...
【讨论】:
以上是关于C# C++/CLR 处理 ref 参数和字符串指针的主要内容,如果未能解决你的问题,请参考以下文章