因此,我在DLL和客户端项目中都包含了这个接口类
// InterfaceClass.h
#pragma once
class InterfaceClass
{
public:
virtual void Update() = 0;
};
这是dll类,它在更新内调用其自身的方法之一
// DLLClassThatDoesSomething.cpp
#include "InterfaceClass.h"
#include <iostream>
#include <string>
class __declspec(dllexport) DLLClass : public InterfaceClass
{
public:
void Update()
{
std::cout << this->GetString();
}
std::string& GetString()
{
std::string thestring = "bruhmoment";
return thestring;
}
};
extern "C"
{
__declspec(dllexport) InterfaceClass* CreateInstance()
{
return new DLLClass();
}
}
这是“客户”项目
// main.cpp
#include "InterfaceClass.h"
#include <Windows.h>
typedef InterfaceClass* (__cdecl *Class) ();
int main()
{
HINSTANCE dll = LoadLibrary(L"DLLClass.dll");
Class klass = (Class)GetProcAddress(dll, "CreateInstance");
InterfaceClass* IKlass = klass();
IKlass->Update();
FreeLibrary(dll);
return 0;
}
调用IKlass->Update()
的那一刻,由于DLLClass调用了它自己的方法,我得到了访问内存冲突的异常。
我没有尝试任何操作,因为我几乎不知道如何在运行时加载DLL,并且我已经使用了这个漂亮的tutorial
我如何让它调用该方法而不会引发异常?我试图让将为我的游戏创建mod的ppl用DLL中的老板,小怪等的自定义类创建自己的mod。
编辑:原来这是我的语法错误。代替return new DLLClass;
,它必须是return new DLLClass();
。修复后,它可以按预期工作。
您返回对局部变量thestring
的引用,并在尝试访问它时std::cout << this->GetString()
,参考数据已被销毁。实际上,它是在声明该变量的复合语句的封闭范围结束后立即销毁的。
有时由于堆栈尚未被覆盖而可能“出现”,但最终会像您的情况一样严重失败。这将触发UB(未定义的行为)。