【问题标题】:crash on "new" when calling a c++ dll from vb从 vb 调用 c++ dll 时在“new”上崩溃
【发布时间】:2014-01-29 14:17:41
【问题描述】:

我正在从一个 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,看到crash就在这一行

    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")

【问题讨论】:

  • 正如我所写 - CAREngine 构造函数是空的
  • 你能展示更多的VB代码吗?就像您如何创建 Engine 实例一样?还是只调用initEngine 成员函数而不使用任何Engine 实例?
  • 这是所有的vb代码。 VB中没有引擎类

标签: c++ vb.net dll crash


【解决方案1】:

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

当您调用实例方法时,有一个隐式参数保存this 的值,并且是.-&gt; 左侧的变量地址。但是,您还没有创建Engine 的实例,您只是调用了一个成员函数。您传入的字符串将用作this 的值,而lpString 参数最终将成为堆栈中的某个随机值。

代码在分配给carEngine 时会崩溃,因为编译器实际上将其视为this-&gt;carEngine,并且当this 指向不是Engine 的东西时,它会失败。

顺便说一句,导出 C++ 成员函数以在 C# 中使用是一项艰巨的工作,正如您所发现的!您必须通过重整名称链接,重整可以从编译器版本更改为编译器版本。

如果您确实需要使用 C++,而您可能想要考虑使用托管 C++。或者,通常公开包装成员函数并采用不透明值的 C 函数,该值实际上是指向它们操作的实例的指针。例如

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

【讨论】:

  • 我不想劫持这个问题,但是(我的c++技能不是最好的)为什么将传递的字符串用作this的值?我知道initEngine 没有实例可以使用,但是为什么要尝试使用函数的第一个参数呢??
  • 所有非静态成员函数都需要有一个this 的值。在幕后,这通常作为第一个参数传入。所以initEngine 被编译器视为initEngine(Engine *this, LPCTSTR DBFilename)。您已经告诉 VB 编译器第一个参数是字符串,但从 C++ 编译器的角度来看,第一个参数是指向要操作的 Engine 实例的指针。
  • 我明白了。所以在没有this-&gt;... 的情况下,第一个参数将始终被视为(yourType *this...)。很好的答案。
  • 第一个参数总是this,不管你有没有放this-&gt;。同样,对成员变量的任何访问都将始终被视为this-&gt;variable,即使您没有提及this
猜你喜欢
  • 2011-10-28
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多