【问题标题】:How to keep alive managed code objects passed to unmanaged code as SWIG shared_ptr's?如何保持活动托管代码对象作为 SWIG shared_ptr 传递给非托管代码?
【发布时间】:2015-10-05 12:28:42
【问题描述】:

所以我想让我的 C++ 代码决定何时销毁托管对象。 (因为它们作为委托传递给它,以便在 C++ 附带事件上调用)。

我有一个简单的对象结构:EventGenerator + Delegates。

在我的托管方面,我有一个 EventGenerator 的包装器和一个 Delegates 接口的包装器,我从中(使用%feature("director"))创建托管委托。在我的 C++ 代码中,我使用 shared_pointers 来让委托保持活跃。我使用了 SWIG 功能 shared_ptr

只要 EventGenerator 还活着,我就需要我的托管 Delegates 还活着。然而 GC 并不知道 EventGenerator 和 Delegates 之间的连接。

但我不想知道对象何时在 C# 方面被销毁 - 我想允许 C++ 方面进行控制(使用 shared_ptr's)。

那么应该如何处理 SWIG 共享指针以使其能够在他管理的方面维持其自身?

我发现的唯一解决方案是在 C# 端扩展 EventGenerator 对象,以便向其添加委托会将该委托添加到列表中。它有效,但我希望有更好的解决方案。

有没有办法使用共享指针引用计数器来制作 SWIG 帐户? (这样委托只会在其 C++ 主机死亡后在托管代码中被销毁?)

【问题讨论】:

    标签: c# c++ delegates swig shared-ptr


    【解决方案1】:

    我相信您最好的选择是使用 GCHandle.Alloc(obj, GCHandleType.Normal); 为托管对象创建 GCHandle只要该句柄存在,该对象就会继续存在(直到您调用 .Free())。您也可以固定对象,但除非您要直接从 C++ 访问对象指针,否则这是不必要的,它会阻止对象在堆压缩等期间被移动。

    在与 C++ 进行 .NET 互操作时,我强烈推荐 C++/CLI。如果您正在使用 C++/CLI,只需创建一个私有引用字段:

    private: MyManagedClass^ fieldName;

    这将存储对对象的引用,这将防止垃圾收集。

    【讨论】:

    • mono/linux是否支持C++/CLI?
    • 不,混合模式程序集自然具有非托管 C/C++ 代码,这些代码是为 Win32/Win64 编译的,并且包括通过 CRT 函数调用 OS 函数,因此尽管 Mono 支持托管,但它不会在 Linux 上运行代码。
    猜你喜欢
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 2010-09-18
    相关资源
    最近更新 更多