leon22
leon22

Reputation: 5669

C++/CLI wrapper for native C++ dll

I have written an C++/Cli wrapper for a native C++ dll, but when I call some method from C# I get an System.AccessViolationException error in my C++/Cli Wrapper dll! It's necessary to marshal the unmanaged types or something else?!

// Wrapper.h

typedef UnmanagedClass* (*Instance)(void);

private:
    UnmanagedClass *m_object; // unmanaged object   

// Wrapper.cpp

Wrapper:Wrapper()
{
    HINSTANCE unmanagedLib;
    unmangedLib = LoadLibrary(SystemStringToLPCSTR(dllPath+dllName));

    // load instance
    Instance _createInstance = (Instance)GetProcAddress(unmangedLib, "GetInstance");
    m_object = (_createInstance)(); 
}

Wrapper::~Wrapper()
{
    m_object->~UnmanagedClass();
}


Uint32 Wrapper::SomeMethod(Uint8 *bytRecvBuffer, int &iRecvLen)
{
    return m_object->SomeMethod(bytRecvBuffer, iRecvLen);
}

// Unmanaged Class

class UnmanagedClass    
{
public:
    /**
    * Default constructor. 
    */
    UnmanagedClass(void);
    /**
    * Default Destructor
    */
    ~UnmanagedClass(void);

    virtual Uint32 Wrapper::SomeMethod(Uint8 *bytRecvBuffer, int &iRecvLen);
};

// export the UnmanagedClass object
extern "C" _declspec(dllexport) UnmanagedClass* GetInstance();

// UnamangedClass.cpp

UnamangedClass::~UnamangedClass(void)
{
    if (UnamangedClassDLL != NULL)
        FreeLibrary(UnamangedClassDLL);

    UnamangedClassDLL = NULL;
}

extern "C" _declspec(dllexport) UnmanagedClass* GetInstance()
{

    return new UnmanagedClass();
}

When I call at example SomeMethod from C# I get the error in C++/Cli dll! (I included the C++/cli dll with add reference in C sharp project and create the Wrapper object)

Thank you for your help!

greets

Upvotes: 2

Views: 4019

Answers (2)

leon22
leon22

Reputation: 5669

I have found the error (System.AccessViolationException):

I'm using an other object in the unmanaged code without initialization (null object -> only declared)!

Init the object with new() and all should run properly!

Upvotes: 0

ildjarn
ildjarn

Reputation: 62995

It is inappropriate to directly call the destructor of an object that was allocated with (non-placement) new. Try changing

m_object->~UnmanagedClass();

to

delete m_object;
m_object = 0;

(m_object = 0; is necessary because unlike a native C++ type's destructor, which may only be called once, an managed type's Dispose implementation may be called repeatedly, and doing so must have defined behavior.)

Or, better yet, in addition to exposing a GetInstance function, also expose a DestroyInstance function and call that instead of using delete so that consuming code does not need to depend on the implementation details of GetInstance (i.e., that it allocates its instance using operator new).

Upvotes: 2

Related Questions