gpt4 book ai didi

visual-c++ - 有效地调用非托管方法,将非托管对象作为托管代码的参数

转载 作者:行者123 更新时间:2023-12-04 06:47:41 25 4
gpt4 key购买 nike

我有以下场景。托管代码将初始化类的许多对象,该类是非托管结构的包装器。为此,我可以采用两种方法。一种是拥有一个托管类包装器,它只有一个指向非托管对象的指针。另一个是拥有一个完整的托管类,并在需要调用非托管方法时创建非托管对象。我提供了以下两种方法。有人告诉我,如果我使用方法 1(有一个指向非托管对象的指针),GC 将有很多关于非托管部分的问题,最好采用方法 2。有人告诉我哪个更好或者是否有是其他一些更好的方法。我对方法 2 的担忧是每次调用非托管方法时都会来回复制。我不确定 GC 问题是否比它更重要。

编辑 - 第一种方法有一个 ref 类,第二种方法有一个值类。第二个是值(value)的原因是它可以更有效地添加到列表中

在非托管中:

struct A_UNMANAGED
{
int a;
int b[20];
};

void GetData(A_UNMANAGED& a); // populates A

托管(第一种方法)

public ref class A_MANAGED
{
A_UNMANGED* ap;

public:
property System::UInt32 a
{
System::UInt32 get() { return ap->a; }
void set(System::UInt32 value) { ap->a = value; }
}

property array<System::UInt32>^ b
{
array<System::UInt32>^ get() { return ap->b; }
void set(array<System::UInt32>^ value) { b = value; } // assume this copy works
}

internal:
void GetData()
{
GetData(ap);
}
};

在托管(第二种方法)中(编辑:更新为引用。假设所有垃圾收集和指针创建都正确编写)

public value class A_MANAGED
{
System::UInt32 a;
array<System::UInt32>^ b;

public:
property System::UInt32 a
{
System::UInt32 get() { return a; }
void set(System::UInt32 value) { a = value; }
}

property array<System::UInt32>^ b
{
array<System::UInt32>^ get() { return b; }
void set(array<System::UInt32>^ value) { b = value; }
}

internal:
void GetUnmanaged(A_UNMANAGED& obj1)
{
obj1.a = a;
pin_ptr<System::UInt32> bp = &b[0];
memcpy(obj1.b, bp, 20);
}

void GetData()
{
A_UNMANAGED obj2;
GetUnmanaged(obj2);
GetData(obj2);
// copy from obj2 to member variables
}
};

最佳答案

不,第一个片段是规范的方式。垃圾收集器只移动指针,不移动指向的对象。那个应该用 malloc() 或 new 运算符分配的,它不能移动。

您的代码中还有几个严重的问题。您似乎没有为 A_UNMANAGED 分配内存,除非 GetData() 通过引用获取其参数。永远不会调用 GetData()。这通常必须是一个 ref 类(而不是 ref 值),因此您可以提供一个析构函数和一个终结器来释放内存。 b 属性 setter 将用 StackOverflowException 轰炸您的程序。在处理这个项目之前一定要学习语言。

检查 this answer示例代码。

关于visual-c++ - 有效地调用非托管方法,将非托管对象作为托管代码的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5657349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com