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 参数和字符串指针的主要内容,如果未能解决你的问题,请参考以下文章

在c#silverlight中调用c++ clr dll

C#中CLR(公共语言运行时)与IL(中间代码)

C#中out和ref之间的区别

C# 结构文档:构造函数初始化器与 `ref` 和 `out` 参数的关系

《CLR via C#》之线程处理——协作式取消和超时

C#“as”运算符和高级转换在循环/函数和 out/ref 参数修饰符和 typeof() [重复]