用于本机C ++ DLL的C ++ / CLI包装器

时间:2011-05-26 07:55:05

标签: c# dll c++-cli unmanaged managed

我为原生C ++ dll编写了一个C ++ / Cli包装器,但是当我从C#调用一些方法时,我的C ++ / Cli Wrapper dll中出现了System.AccessViolationException错误!有必要整理非托管类型或其他东西吗?!

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

当我从C#调用示例SomeMethod时,我得到了C ++ / Cli dll中的错误! (我在C sharp项目中包含了C ++ / cli dll和add reference,并创建了Wrapper对象)

感谢您的帮助!

招呼

2 个答案:

答案 0 :(得分:2)

直接调用分配了(非展示位置)new的对象的析构函数是不合适的。尝试更改

m_object->~UnmanagedClass();

delete m_object;
m_object = 0;

m_object = 0;是必要的,因为与本机C ++类型的析构函数(可能只调用一次)不同,可能会重复调用托管类型的Dispose实现,并且这样做必须具有已定义的行为。)< / p>

或者,更好的是,除了公开GetInstance函数之外,还要公开DestroyInstance函数并调用它而不是使用delete,以便消耗代码不需要依赖于GetInstance的实现细节(即,它使用operator new分配其实例)。

答案 1 :(得分:0)

我发现错误(System.AccessViolationException):

我在非托管代码中使用其他对象而没有初始化(null对象 - &gt;仅声明)!

使用new()初始化对象,并且所有对象都应该正常运行!