【问题标题】:Pass int by reference from C++/CLI to C#通过引用从 C++/CLI 将 int 传递给 C#
【发布时间】:2015-05-13 00:06:23
【问题描述】:

好像肯定有重复的问题,但我一直没找到。

我正在写一个桥来让一个旧的 C 程序访问一些 C# 对象。桥是用 C++/CLI 编写的。

在一种情况下,有一个 C# 函数定义为:

public static string GetNameAndValue(out int value);

我的 C++/CLI 包装函数:

char* GetNameAndValue(int* value);

从 C 调用很容易。但是如何从 C++/CLI 调用 C# 方法?

我首先尝试了显而易见的:

String ^ str;
str = TheObject::GetNameAndValue(value);

这给了我错误 C2664:无法将参数 2 从 'int *' 转换为 'int %'。

好的,那么,GetNameAndValue(%value) 怎么样?这给了我错误 C3071: operator '%' can only be applied to an instance of a ref class or a value-type.

很公平。所以如果我创建一个int 我可以通过%??

int foo;
str = TheObject::GetNameAndValue(%ix);

没有骰子。又是 C3071。我觉得很奇怪,因为int 绝对 一个值类型。还是这样?

肯定有 %、^、& 或其他一些淫秽的魔法组合可以满足我的要求,但在这件事上咒骂了 30 分钟后,我被难住了。在 Google 上搜索 C++/CLI 和 C# 的不同组合,主要是提供有关如何从 C# 调用 C++ 的信息。

所以,我的问题:如何将 int 从 C++/CLI 传递给需要 out int(或 ref int,如果我必须)的 C# 方法?

【问题讨论】:

  • 你的事情严重倒退了。 C++/CLI 在允许 C 程序调用 C# 方法方面毫无用处。它是一种语言扩展,从托管代码到本机代码。从本机程序运行托管代码需要更大的武器,它必须首先加载和初始化 CLR。这需要 30 多分钟才能解决。
  • @HansPassant:这不是我在很短的时间内工作的经验。我的 C 程序调用一个用 C++/CLI 编译的 DLL,而后者又调用另一个程序集中的 C# 代码。效果很好。据我了解,C++/CLI DLL 加载运行时。无论如何,我已经能够将 C# 代码中的信息返回到 C 代码中。
  • C++/CLI 支持 __declspec(dllexport),这是我能想到的唯一一个可以让你好运的场景。与 Giesecke 的 [DllExport] hack 的想法相同。如发布的那样,您的问题对我来说毫无意义,您遇到的问题是完全正常的。祝你好运。

标签: c# c++-cli


【解决方案1】:

C#:

class MyClass 
{ 
    public static string GetNameAndValue(out int value);
}

C++/CLI:

int value;
String^ x = MyClass::GetNameAndValue(value);

C++/CLI 包装器:

CString GetNameAndValue(int* value)
{
    String^ x = MyClass::GetNameAndValue(*value);
    return CString(x);
}

C++/CLI 封装 2:

CString GetNameAndValue(int& value)
{
    String^ x = MyClass::GetNameAndValue(value);
    return CString(x);
}

对于 C#“ref”也是一样。

【讨论】:

  • 完全不明显!因此,当我执行MyClass::GetNameAndValue(*value) 时,编译器会自动将其编组为[out] System::Int32?这需要我一点时间来测试,但如果它有效,我会接受答案。
  • 这就像调用 C++: "void x(int&);"通过传递变量“int v;”。机制是一样的。没有演员表。对于编译器,所需的原型与定义的原型相同。
  • ref 和 out 之间的唯一区别是 out 强制你在方法内部分配变量。否则,您可以将 ref 视为 C++ &。顺便说一句,我用了一段时间的 C++、C++/CLI、C# 并且真的不需要使用 % 符号,你可以在 C# 或 C++ 中定义它的等价物。所以在 C++/CLI 中,唯一需要关心的附加引用类型符号是 ^.
  • 没有办法在 C++ 中定义跟踪引用之类的东西。 C++/CLI 中的% 是独一无二的,因为它会在对象在堆压缩期间移动时跟随它们。对象在其生命周期内四处移动是 .NET 的一个独特功能。它在 C++ 中不存在,因此没有用于匹配引用的工具。
【解决方案2】:

我知道这个问题已经得到解答,但只是为了澄清编译器使用“C2664:无法将参数 2 从 'int *' 转换为 'int %'”的建议。
我认为它想要这个(C++/CLI):

int a=5
int% foo=a;
str = TheObject::GetNameAndValue(foo);

【讨论】:

  • 并非如此。它是一个引用参数,可以绑定到一个左值。您不需要在调用者中创建另一个引用......并且参数不会无论如何都绑定到调用者的引用。
  • 我的帖子的重点和目的是明确和清晰,没有花哨的术语。你当然是正确的,但非常学术。我认为简单甚至过于琐碎的例子更好。这其实是 MSDN 的问题:写得很学术,所以反直觉,很难在短时间内掌握。这就是为什么我们有这样的网站。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 2020-11-19
  • 2012-06-25
  • 2020-05-03
  • 2023-03-19
  • 1970-01-01
相关资源
最近更新 更多