我遇到了一个问题,在 C++ 函数中使用 new 为结构分配内存无法正确地将实例传输回 C#。
似乎正确的方法是避免new
在 C++ 函数中使用并直接设置 out 参数的值。但是,我找不到明确描述此行为或解释 out 参数如何自动处理实例创建的文档。您在 Microsoft Document 的某个地方有此信息吗?我想知道您是否知道。
C++代码:
struct MyStruct {
int value1;
float value2;
};
extern "C" __declspec(dllexport) void GetValues(MyStruct* outStruct) {
// outStruct = new MyStruct(); // NG
outStruct->value1 = 42;
outStruct->value2 = 3.14f;
}
C# 代码:
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct {
public int value1;
public float value2;
}
[DllImport("MyNativeLib.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void GetValues(out MyStruct result);
public static void TestInterop() {
MyStruct result;
GetValues(out result);
}
答案是:不是。
我不知道具体的文档是否说明了这一点,这只是 C++ 如何工作的一个基本问题,与 P/Invoke 无关。
他们没有。
实例的创建是在 C# 端完成的,具体方法如下:
请注意,由于
MyStruct
是结构,因此是值类型,因此不需要new
ing(尽管它是可选的)。实例是在堆栈上创建的。然后将
指向此实例的指针(
outStruct
)传递给 C++,并由 C++ 函数通过此指针填充。附注:使用inside没有达到预期效果
的原因是,在 C++(以及 C)中,参数通常是按值传递的(在 C++ 中,我们也有按引用传递,但这里不是这种情况)。 在这种情况下,指针(保存地址)按值传递。在函数中更改指针本身不会影响调用者。 为了影响调用者,您需要传递一个指向指针的指针。 有关更多信息,请参阅此帖子:C++ 为什么使用双指针作为 out/return 函数参数?。
outStruct = new MyStruct();
GetValues