从vb调用c ++ dll时崩溃“new”

时间:2014-01-29 14:17:41

标签: c++ vb.net dll crash

我正在从cpp项目创建一个dll。 从vb项目调用此dll时,应用程序崩溃。 有这个错误消息:

    An unhandled exception of type 'System.AccessViolationException' occurred in...
    Additional information: Attempted to read or write protected memory. This is often 
    an indication that other memory is corrupt.

我可以调试dll,看看崩溃就在这行

    carEngine = new CAREngine ();

CAREngine构造函数为空。什么可能导致这次崩溃?

以下是代码:

C ++ .h文件:

    #include "CarEngine.h"

    class Engine
    {
    public:
        bool __declspec(dllexport) initEngine(LPCTSTR DBfileName);
    private:
        CAREngine* carEngine;
    };

C ++ .cpp文件:

    bool Engine::initEngine(LPCTSTR DBfileName)
    {
        logText("Engine Loading start");
        carEngine = new CAREngine ();  //<- Crash is here
        ...
    }

VB:

    <DllImport("myengine.dll", EntryPoint:="?    
    initEngine@Engine@@QAE_NPBD@Z")> _
    Public Function initEngine(ByVal lpString As String) As Boolean
    End Function

    ...

    initEngine("C:\1.txt")

1 个答案:

答案 0 :(得分:4)

initEngine是一种实例方法,但您将其视为独立方法。

当您调用实例方法时,theres是一个隐含参数,其中包含this的值,并且是.->左侧变量的地址。但是,您尚未创建Engine的实例,您刚刚调用了成员函数。您传入的字符串将用作this的值,lpString参数将最终成为堆栈中的随机值。

代码将在分配给carEngine时崩溃,因为编译器实际上将其视为this->carEngine,而this指向的内容不是Engine失败。

顺便说一句,导出C ++成员函数以便在C#中使用是很难的,因为你已经发现了!您必须通过错位名称进行链接,并且修改可以从编译器版本更改为编译器版本。

如果您真的需要使用C ++,可能需要考虑使用托管C ++。另外,通常会公开包含成员函数的C函数并获取一个opaque值,该值实际上是指向它们所操作的实例的指针。例如

void *EngineCreate();
void EngineInitialize(void *engine)
void EngineSetName(void *engine, const TCHAR *name)
// etc
// etc