问题描述
我有一个计算缓冲区大小的C ++函数:
I have a C++ function that calculates a buffer size:
CalcBuffer(unsigned long long* bufferSize);
我想稍后在我的C#代码中将此结果传递给另一个函数.我的C ++ \ CLI包装器看起来像这样:
I want to pass this result into a different function later in my C# code.My C++\CLI Wrapper looks like this:
CalcBufferWrapper([Out] UInt64^% bufferSize){
CalcBuffer(bufferSize);
}
但是我遇到了这个错误:
But I'm getting this error:
很明显,我需要使用其他类型,但是使用哪种类型?
Obviously, I need to use a different type, but which type?
推荐答案
UInt64^%
并不意味着您认为的那样. ^
帽子仅应用于引用类型,UInt64是值类型.大约99%的时间这样做是错误的,但是C ++/CLI编译器仍然接受它并将其解释为对 boxed 64位无符号整数的引用".装箱转换将值转换为对象,实现了著名的幻想,即值类型也从System :: Object派生.
UInt64^%
doesn't mean what you think it does. The ^
hat should only be used on reference types, UInt64 is a value type. Doing this is wrong about 99% of the time but the C++/CLI compiler accepts it anyway and interprets it as "reference to a boxed 64-bit unsigned integer". A boxing conversion turns a value into an object, implements the famous illusion that value types also derive from System::Object.
当然与不带符号的long long *不兼容.请检查您的代码,以确保您不会在其他地方意外使用^帽子.这是一个严重的处理器周期下降,使代码慢了大约一个数量级.
Which certainly is not compatible with an unsigned long long*. Do review your code to ensure that you don't accidentally use the ^ hat inappropriately elsewhere. It is a drastic processor cycles sink, makes code about an order of magnitude slower than it needs to be.
您必须停止使用帽子.并处理添加它的可能原因,即UInt64 可能是托管对象的字段.运行本机代码时,垃圾收集器可以移动哪个 .那将是完全灾难性的(本机代码现在破坏了堆),因此编译器将不允许这样做.您必须提供无法移动的值的稳定副本:
You have to stop using the hat. And deal with the possible reason you added it, that UInt64 might be a field of a managed object. Which might be moved by the garbage collector while the native code is running. That would be utterly disastrous (the native code now corrupts the heap) so the compiler won't allow it. You have to provide a stable copy of the value that cannot move:
void CalcBufferWrapper(UInt64% bufferSize) {
auto size = bufferSize; // Values on the stack don't move
CalcBuffer(&size);
bufferSize = size;
}
或者好很多,完全不需要给包装器提供与包装函数完全相同的签名:
Or much better, no need at all give the wrapper the exact same signature as the wrapped function:
UInt64 CalcBufferWrapper() {
unsigned long long size;
CalcBuffer(&size);
return size;
}
这也应该是一个属性的可能性很小.
Some odds that this should be a property as well.
这篇关于C ++ \ CLI-如何将UInt64 ^%转换为unsigned long long *的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!