是否可以通过引用将int从C#传递到C ++?
在C ++中,我有一个简单的方法,它只是增加一个数字并打印消息。
void ProcessOrder(int& num)
{
int start = num;
int stop = num + 10;
for (int i = start; i < stop; i++)
{
cout << "[Legacy] counting " << i << endl;
}
cout << endl;
// Note the above was original posted code and I made a stupid mistake and was never
// even changing `num` value passed by reference. The correct function to test
// should be as below (discard all of the above)
num = num + 5; // just modify the number to any value
}
现在我想从C ++ / CLI中调用它,然后从C#中调用它。
void StoreWrapper::ProcessOrder(int^ num)
{
LegacyStore* legacyStore = new LegacyStore();
legacyStore->ProcessOrder(num); // error here
}
但这会返回编译器错误:
error C2664: 'void LegacyStore::ProcessOrder(int &)': cannot convert argument 1 from 'System::Int32 ^' to 'int &'
我确保所有三个项目均为x86,但错误仍然存在。价格上,CLR模块是Win32,C#控制台应用程序是x86。
问题在这里:
如果我声明void StoreWrapper::ProcessOrder(int& num)
,则此方法可以编译,但现在我相信它是纯C ++?我不能从C#端调用此命令,请获得以下编译器错误:
error CS1503: Argument 1: cannot convert from 'int' to 'int*'
如果我将其声明为“ void StoreWrapper :: ProcessOrder(int ^ num)”,则该方法甚至无法编译。
我尝试使用System::Int32
变量类型,但结果相同。
有没有一种方法可以通过引用从.NET world将int传递给C ++? C ++端是32位,.NET端是64位,可以吗?
更新
C#代码在这里,基本上我希望该代码在下面的代码中得到更新。
int number = 0;
Console.WriteLine("Original number = {0}", number);
store.ProcessOrder(ref number);
Console.WriteLine("After ProcessOrder number = {0}", number);
不幸的是,dxiv的回答并没有更新上面的数字。
答案 0 :(得分:0)
尝试像num
一样直接使用ProcessOrder(num);
失败,原因是原始帖子“ 无法将参数1从System::Int32 ^
转换为int &
”,因为所传递的(指针)变量和预期的(引用)参数之间的间接级别不同。
尝试用ProcessOrder(*num);
修复该错误,可以纠正间接寻址并获取匹配的类型,但编译失败,并出现错误“ gc堆中的对象(未装箱的值类型)无法转换为本地参考”。这指出了一个真正的问题,那就是未托管/未装箱的引用无法指向gc托管堆,这会受到压缩和重新排序。
最简单的解决方案是改为使用tracking reference int%
,如answer所建议的那样,将问题链接为重复项。
void StoreWrapper::ProcessOrder(int% num)
{
LegacyStore* legacyStore = new LegacyStore();
legacyStore->ProcessOrder(*&num); // shorthand for:
//
// int &n = *#
// legacyStore->ProcessOrder(n);
// num = n;
}
// to be called from C# as:
//
// int number = 0;
// store.ProcessOrder(ref number);
num
。
void StoreWrapper::ProcessOrder([System::Runtime::InteropServices::Out] int %num)
{
LegacyStore* legacyStore = new LegacyStore();
pin_ptr<int> p = #
legacyStore->ProcessOrder(*p);
}
// to be called from C# as:
//
// int number = 0;
// store.ProcessOrder(out number);