2014-05-12 62 views
8

似乎必须有一个重复的问题,但我一直没能找到它。通过引用从C++/CLI传递给C#

我正在编写一个桥梁让旧的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。

好的,那么GetNameAndValue(%value)怎么样?这给了我错误C3071:运算符'%'只能应用于ref类或值类型的实例。

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

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

没有骰子。再次C3071。其中我觉得奇怪,因为int绝对是的一种值类型。或者是?

必须有%,^,&或一些其他淫秽的魔术组合,将做我想做的事情,但在这个事情发誓30分钟后,我很难过。在Google搜索C++/CLI和C#的不同组合大多提供了有关如何从C#调用C++的信息。

SO,我的问题:你如何将C++/CLI中的int传递给期望out int(或ref int,如果必须的话)的C#方法?

+1

你有事情严重倒退。 C++/CLI很容易让C程序调用C#方法。它是从托管代码到本地代码的另一种方式的语言扩展。从本地程序运行托管代码需要更大的武器,它必须首先加载并初始化CLR。这将需要超过30分钟才能理清。 –

+1

@HansPassant:这不是我在短时间内的工作经验。我的C程序调用一个用C++/CLI编译的DLL,而C++/CLI又调用另一个程序集中的C#代码。工作得很好。据我了解,C++/CLI DLL加载运行时。无论如何,我已经能够将C#代码中的信息返回给C代码。 –

+0

C++/CLI支持__declspec(dllexport),这是我能想到的唯一场景,您可以从中获得好运。与Giesecke的[DllExport]黑客相同的想法。正如所发布的,你的问题对我来说毫无意义,你遇到的问题完全正常。祝你好运。 –

回答

5

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”是一样的。

+0

那*完全*不明显!所以当我执行'MyClass :: GetNameAndValue(* value)'时,编译器会自动封送它为''[out] System :: Int32''吗?它会花一点时间来测试,但如果它有效,我会接受答案。 –

+2

就像调用C++一样:“void x(int&);”通过传递变量“int v;”。机制是一样的。没有演员。对于编译器来说,所需的原型与定义的原型相同。 –

+0

更重要的是ref和out之间的唯一区别是,强迫你在方法内部分配变量。否则,您可以将ref视为C++&。顺便说一句,我使用C++,C++/CLI,C#一段时间,并且实际上不需要使用%符号,您可以在C#或C++中定义它。所以在C++/CLI中,唯一需要关注的附加引用类型符号是^。 –

0

我知道这已经回答了,但只是为了澄清编译器提示“C2664:无法将参数2从'int *'转换为'int%'”。
我认为它希望这个(C++/CLI):

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

不是。它是一个引用参数,可以绑定到一个左值。你不需要在调用者中创建另一个引用......并且参数**不会绑定到调用者的引用。 –

+1

我的文章的重点和目的是明确而清晰的,没有花哨的条款。你当然是对的,但很有学术价值。我认为简单的甚至过分平凡的例子都更好。这实际上是MSDN的问题:它是以一种非常学术的方式编写的,因此它是反直觉的,很难在短时间内掌握。这就是为什么我们有像这样的网站。 – Pifcnt