How to call a native method with a std::vector as argument and retrieve the native object in wrapped class

48 views Asked by At

I have a native C++ method, from external unchangable DLL, that expects a std::vector as a argument with 2 native objects. (for example sake, it's an image library returning width/height of a 2 images)

I would like the native objects in the std::vector to be referenced in my own wrapped MyManagedImageObj.

Somehow the std::vector seems to copy values and has no way to add pointers (correct?); so after calling the NativeMethod; I need to copy the properties (width/height) back again to MyManagedImageObj.

I thought about first declaring the std::vec and getting the pointer of the results and put that in MyManagedImageObj as a pointer. But if I understand it correctly std::vector will clean that native memory up once out of scope. (my c++ experience is 1 week; c# long time)

Is there a better way to do this without reassigning the properties one by one?

Ej

The code looks like this:

//create managed object that wraps also native pointer. 
MyManagedImageObj^ obj1 = gcnew MyManagedImageObj();
MyManagedImageObj^ obj2 = gcnew MyManagedImageObj();

//keep list of result
List<MyManagedImageObj^>^ resultList;
resultList->Add(obj1);
resultList->Add(obj2);

//call to native method. Dereference pointers of native wrapped objects... not working? 
std::vector<DLLNativeImageObj> nativeImageVec { *obj1->GetInstance(), *obj2->GetInstance() };
bool result = otherNativePtr->NativeMethod(nativeImageVec);

//we still need copy it over results now to 'our' managed objects.  
int i = 0;
for (DLLNativeImageObj c : nativeImageVec)
{
    resultList[i]->ImageHeight = c.imageHeight;
    resultList[i]->ImageWidth = c.imageWidth;
    ++i;
}

The MyManagedImageObj class looks like this:

//MyManagedImageObj.h

public ref class MyManagedImageObj
{
protected: 
    DLLNativeImageObj* m_Instance;
public:
    MyManagedImageObj(DLLNativeImageObj* instance)
        : m_Instance(instance)
    {
    };
    
    ~MyManagedImageObj() //destructor will be called whenever we do 'delete' 
    {
        if (m_Instance != nullptr)
        {
            delete m_Instance;
        }
    }
    
    !MyManagedImageObj() //finalizer, called by the garbage collector when it's destroys the wrapper object. So safety check to dispose unmanaged item. 
    {
        if (m_Instance != nullptr)
        {
            delete m_Instance;
        }
    }

    DLLNativeImageObj* GetInstance() //return the pointer to the unmanaged object
    {
        return m_Instance;
    }
    
    property uint32_t ImageWidth
        {
        public:
            uint32_t get()
            {
                return m_Instance->imageWidth;
            }
        public:
            void set(uint32_t value)
            {
                m_Instance->imageWidth = value;
            }
        }

        property uint32_t ImageHeight
        {
        public:
            uint32_t get()
            {
                return m_Instance->imageHeight;
            }
        public:
            void set(uint32_t value)
            {
                m_Instance->imageHeight = value;
            }
        }
};

//MyManagedImageObj.cpp
MyManagedImageObj::MyManagedImageObj(new DLLNativeImageObj())
    {
        // new keyword important: it returns a pointer to the location and does not get deleted when out of scope. Manual delete is required. 
    }


0

There are 0 answers