C++\CLI - 如何将 UInt64^% 转换为 unsigned long long*

C++\CLI - How to convert UInt64^% to unsigned long long*

我有一个计算缓冲区大小的 C++ 函数:

CalcBuffer(unsigned long long* bufferSize);

我想稍后在我的 C# 代码中将此结果传递给另一个函数。 我的 C++\CLI 包装器如下所示:

CalcBufferWrapper([Out] UInt64^% bufferSize){
     CalcBuffer(bufferSize);
}

但是我收到这个错误:

argument of type "System::UInt64 ^" is incompatible with parameter of type "unsigned long long *".

显然,我需要使用不同的类型,但是是哪种类型呢?

UInt64^% 并不代表您认为的那样。 ^ 帽子只能用于引用类型,UInt64 是一种值类型。这样做在大约 99% 的情况下都是错误的,但 C++/CLI 编译器无论如何都会接受它并将其解释为 "reference to a boxed 64-bit unsigned integer"。装箱转换将值转换为对象,实现了值类型也从 System::Object 派生的著名错觉。

这肯定与 unsigned long long* 不兼容。请检查您的代码,以确保您不会意外地在其他地方不恰当地使用 ^ 帽子。这是一个严重的处理器周期下沉,使代码比需要的速度慢一个数量级。

你必须停止使用这顶帽子。并处理您添加它的可能原因,即 UInt64 可能 是托管对象的字段。 可能 被垃圾收集器移动,而本机代码是 运行。那将是完全灾难性的(本机代码现在破坏了堆)所以编译器不会允许它。您必须提供无法移动的值的稳定副本:

void CalcBufferWrapper(UInt64% bufferSize) {
     auto size = bufferSize;      // Values on the stack don't move
     CalcBuffer(&size);
     bufferSize = size;
}

更好,根本不需要为包装器提供与包装函数完全相同的签名:

UInt64 CalcBufferWrapper() {
   unsigned long long size;
   CalcBuffer(&size);
   return size;
}

有些可能性这也应该是 属性。