Оболочка C ++ / CLI для нативной C ++ dll - PullRequest
2 голосов
/ 26 мая 2011

Я написал оболочку C ++ / Cli для нативной DLL C ++, но когда я вызываю какой-то метод из C #, я получаю ошибку System.AccessViolationException в моей DLL C ++ / Cli Wrapper!Необходимо маршалировать неуправляемые типы или что-то еще?!

// 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();
}

Когда я вызываю пример SomeMethod из C #, я получаю ошибку в C ++ / Cli dll!(Я включил C ++ / cli dll с добавлением ссылки в проект C sharp и создал объект Wrapper)

Спасибо за вашу помощь!

greets

Ответы [ 2 ]

2 голосов
/ 26 мая 2011

Неуместно напрямую вызывать деструктор объекта, который был выделен (без размещения) new. Попробуйте изменить

m_object->~UnmanagedClass();

до

delete m_object;
m_object = 0;

(m_object = 0; необходимо, потому что в отличие от деструктора нативного типа C ++, который может вызываться только один раз, реализация Dispose управляемого типа может вызываться повторно, и это должно иметь определенное поведение.)

Или, что еще лучше, в дополнение к представлению функции GetInstance, также представьте функцию DestroyInstance и вызовите ее вместо использования delete, так что использование кода не должно зависеть от деталей реализации GetInstance (то есть, что он выделяет свой экземпляр, используя operator new).

0 голосов
/ 31 мая 2011

Я обнаружил ошибку (System.AccessViolationException):

Я использую другой объект в неуправляемом коде без инициализации (нулевой объект -> только объявлен)!

Инициируйте объект с помощью new (), и все должно работать правильно!

...