从本机 C++ 返回向量dll 转换为托管 C++/CLI dll

发布于 2024-11-08 20:40:36 字数 658 浏览 4 评论 0原文

我正在围绕无法更改的本机 C++ dll 编写 CLI/C++ 包装器。本机 DLL 的函数之一返回非托管对象的向量。在我的 CLI 包装器中包装这个向量的最佳方式是什么? CLI 包装器将由 C# 应用程序使用。

class __declspec(dllexport) Instrument
{
  public:
        Instrument();
        ~Instrument();
        string _type;
        unsigned int _depth;
}

本机 DLL 具有 getInstruments() 函数,这就是我想要包装的函数

 class __declspec(dllexport) InstrumentList
   {
       InstrumentList();
       ~InstrumentList();
       vector<Instrument*> getInstruments();
   }

,因此我需要将仪器类包装在托管类中,并将 InstrumentList 类包装在托管类中。我包装了 Instrument 类,但需要将 getInstruments() 返回的向量转换为 InstrumentList 的 CLI 包装器可以返回的等效内容。

I'm writing a CLI/C++ wrapper around a native C++ dll which can not be changed. One of the functions of the native DLL returns a vector of unmanaged objects. What would be the best way to wrap this vector in my CLI wrapper? The CLI wrapper is going to be used by a C# application.

class __declspec(dllexport) Instrument
{
  public:
        Instrument();
        ~Instrument();
        string _type;
        unsigned int _depth;
}

The native DLL has the function getInstruments() which is what I'm trying to wrap

 class __declspec(dllexport) InstrumentList
   {
       InstrumentList();
       ~InstrumentList();
       vector<Instrument*> getInstruments();
   }

So I need to wrap the instrument class in a managed class and wrap InstrumentList class in a managed class. I have the Instrument class wrapped, but need to convert the vector returned by getInstruments() into something equivalent that the CLI wrapper for InstrumentList can return.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伴我老 2024-11-15 20:40:36

除非您想延迟 Instrument::_type 的编组直到访问其托管外观,否则这应该可以帮助您开始:

public ref class InstrumentM
{
    String^ _type;
    unsigned _depth;

internal:
    explicit InstrumentM(Instrument const& i)
      : _type(gcnew String(i._type.c_str())),
        _depth(i._depth)
    { }

public:
    property String^ Type { String^ get() { return _type; } }
    property unsigned Depth { unsigned get() { return _depth; } }
};

public ref class InstrumentListM
{
    InstrumentList* _list;

public:
    InstrumentListM() : _list(new InstrumentList()) { }
    ~InstrumentListM() { this->!InstrumentListM(); }
    !InstrumentListM()
    {
        delete _list;
        _list = nullptr;
    }

    array<InstrumentM^>^ GetInstruments()
    {
        if (!_list)
            throw gcnew ObjectDisposedException(L"_list");

        vector<Instrument*> const& v = _list->getInstruments();
        array<InstrumentM^>^ ret = gcnew array<InstrumentM^>(v.size());
        for (int i = 0, i_max = ret->Length; i != i_max; ++i)
            if (v[i])
                ret[i] = gcnew InstrumentM(*v[i])
        return ret;
    }
};

Unless you want to delay the marshaling of Instrument::_type until its managed facade is accessed, this should get you started:

public ref class InstrumentM
{
    String^ _type;
    unsigned _depth;

internal:
    explicit InstrumentM(Instrument const& i)
      : _type(gcnew String(i._type.c_str())),
        _depth(i._depth)
    { }

public:
    property String^ Type { String^ get() { return _type; } }
    property unsigned Depth { unsigned get() { return _depth; } }
};

public ref class InstrumentListM
{
    InstrumentList* _list;

public:
    InstrumentListM() : _list(new InstrumentList()) { }
    ~InstrumentListM() { this->!InstrumentListM(); }
    !InstrumentListM()
    {
        delete _list;
        _list = nullptr;
    }

    array<InstrumentM^>^ GetInstruments()
    {
        if (!_list)
            throw gcnew ObjectDisposedException(L"_list");

        vector<Instrument*> const& v = _list->getInstruments();
        array<InstrumentM^>^ ret = gcnew array<InstrumentM^>(v.size());
        for (int i = 0, i_max = ret->Length; i != i_max; ++i)
            if (v[i])
                ret[i] = gcnew InstrumentM(*v[i])
        return ret;
    }
};
櫻之舞 2024-11-15 20:40:36

您可能根本不想包装 InstrumentList。

只需使用一个库存 .NET 集合(您可以从 C++/CLI 访问)并创建一个 Instrument 包装器集合。自从我想将数据绑定到我的集合以来,我一直在使用 ObservableCollection。

示例:

public ref class MyManagedType
{
    public:
        MyManagedType(MyNativeType* pObject) { m_pObject = pObject };

    private:
        MyNativeType* m_pObject;
}

然后像这样创建托管集合:

ObservableCollection<MyManagedType^>^ managedCollection = gcnew ObservableCollection<MyManagedType^>();

最后,将对象添加到集合中:

managedCollection->Add(gcnew MyManagedType(pNativeObject));

保持本机集合和托管集合同步需要花费一些精力,但效果很好。

You may not want to wrap the InstrumentList at all.

Just use one of the stock .NET collections (which you can access from C++/CLI) and make a collection of your Instrument wrappers. I've been using ObservableCollection since I want to databind to my collections.

Example:

public ref class MyManagedType
{
    public:
        MyManagedType(MyNativeType* pObject) { m_pObject = pObject };

    private:
        MyNativeType* m_pObject;
}

Then create the managed collection like this:

ObservableCollection<MyManagedType^>^ managedCollection = gcnew ObservableCollection<MyManagedType^>();

Finally, add objects to the collection:

managedCollection->Add(gcnew MyManagedType(pNativeObject));

It's a bit of effort to keep the native and managed collections in sync, but it works well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文