gpt4 book ai didi

c++ - 从 vb 调用 c++ dll 时在 "new"上崩溃

转载 作者:行者123 更新时间:2023-11-30 01:54:52 26 4
gpt4 key购买 nike

我正在从一个 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")

最佳答案

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

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

代码将在分配给 carEngine 时崩溃,因为编译器实际上将其视为 this->carEngine,并且 this 指向某物那不是 Engine 它会失败。

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

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

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

关于c++ - 从 vb 调用 c++ dll 时在 "new"上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21433705/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com