将指向对象的指针传递给 dll
Pass pointer to object to dll
我正在编写这个编辑器.exe程序,它加载一个游戏.dll,获取dll内函数的地址,并将指针传递给一个核心对象。
gameInitFuncPtr init =
(gameInitFuncPtr) GetProcAddress(LoadLibraryA("game.dll"),"gameInit");
init(&core); // core is already instanced somewhere, maybe on the stack
游戏.dll包括定义核心类的 core.h。 核心类被实现并编译到编辑器.exe中。
在 dll 端,从传递的对象指针调用函数会导致未解析的外部符号
调用游戏.dll 使用给定对象指针的示例是:
void gameInit(ldk::Core* core)
{
_core->renderer.drawText("initializing...");
}
如何编译 dll 以便它不会尝试在 dll 模块中找到例如 drawText() 实现?
1 - 请注意,这不是一个关于如何声明指向成员函数的指针的问题。
2 - 我知道如果我传递一个仅带有指向方法的指针的结构,它很容易修复,但我对此真的很好奇。
3 - 我正在使用Microsoft的cl编译器18.00,这是Visual Studio 2013附带的编译器
我遇到了与您类似的问题,设置几乎相同 - 游戏作为 dll 和引擎作为 exe。以下是有关如何解决此问题的一些说明。
仅调用虚拟方法。正如你所指出的,如果你调用的方法没有声明为虚拟,链接器会尝试为它找到一个实现并失败(如果它不在标头中 - 我们试图避免的事情)。该方法不需要抽象,虚拟就足够了。另外,请注意,在结构Renderer
中,你可以使用非虚拟方法,只要不从 dll 调用它们(如果这样做,链接器会抱怨)。拥有这样的接口可能是不可取的,最好有某种只有虚拟公共方法的 API 类,这样此类的用户就不会犯错误。
从 dll 使用的所有类都需要共享或仅标头。我的意思是,据我所知,没有神奇的方法,在标头中声明类,在 cpp 中实现,编译为 exe,然后从 dll 使用这些类。例如,如果你有一个自定义字符串类,它需要位于共享库中。如果它只是在 exe 中,您将无法在 dll 中实例化它(从函数等返回它)。对此的解决方案是使用仅标头类。例如,您的字符串可以在编辑器项目的标头中实现,并且此标头可能包含在您的游戏项目中。这样,您基本上可以将相同的代码编译为 exe 和 dll。
要查看一个小的工作示例,请参阅我的VS 2017解决方案存储库,该存储库演示了此确切问题,仅此而已。 回购链接。
这个问题的更大工作示例可以在idTech4引擎 - DOOM 3版本中看到。它还使用游戏作为 dll 和引擎作为 exe。并且还需要交换指向游戏中使用的引擎系统的指针。这个项目很大,但如果你从Game.h
一直看一下项目Game-d3xp
类,他们有一个游戏的 API 和一个函数GetGameAPI_t
,它期望获得带有指向引擎系统的指针gameImport_t
结构,并返回带有游戏信息的gameExport_t
。然后加载发生在Common.cpp
如您所见,他们在各自的项目中使用共享库idLib
来执行诸如idString
之类的事情。从 dll 使用的所有引擎类通常都非常小,并且仅在标头中实现(它们大多是结构)。
请注意,id本身正在远离这种架构,甚至他们最新版本的DOOM 3 - DOOM 3 BFG版本也编译为单个exe,模块是静态库而不是dll。
不清楚你在哪里初始化_core
.乍一看,gameInit
应该这样做。
声明接口类Core
,即它应该是抽象的。在后继类中实现它,例如exe中的CoreImpl。这将修复未解析的外部符号。
看来我想多了。 温编译编辑器.exe核心灵魂被声明只是链接任何类。
struct Core
{
struct Renderer
{
void drawText(const char* text);
}
...
}
但是,由于编辑器和游戏.dll共享相同的 Core.h,因此我使用宏将 Core.h 成员函数的声明修改为纯虚拟,例如:
struct Core
{
struct Renderer
{
virtual void drawText(const char* text) = 0;
}
...
}
所以未解析的外部符号链接错误消失了
但是:我在运行时没有按预期工作! :(
- Visual c ++,使用字符串引用/指针调用 dll 函数
- 读取进程内存多级指针(DLL 注入)
- 函数指针分配在创建 DLL 后导致错误
- 正在从jvm.dll获取FindClass函数指针
- DLL 导出导致唯一指针出现问题
- 全局外部指针变量在 DLL 中不可见
- 如何使用指针作为参数在 C# 中包装C++ DLL?
- 使用指针调用C++ DLL 函数
- 访问违规读取位置传递指针以在c中写入的DLL中起作用
- 将指向对象的指针传递给 dll
- 如何从C DLL返回的指针中获得VBA中的整个矩阵
- 如何将函数指针从 C# 传递到C++ Dll
- 在多个线程中使用 DLL 函数指针
- 当参数之一是指针数组时,如何从C#调用C DLL
- 通过功能指针通过DLL进行回调功能,运行时检查失败#0错误
- 使用抽象接口C++ dll 边界 -标头中的智能指针>?叫删除?
- DLL函数导出一个指针做Delphi程序
- 当从一个应用程序调用时,在DLL方法中创建COM接口指针是有效的,但当从另一个应用软件调用时则无效
- 从CUDA中的指针加载图像并导出dll
- 通过指针值将数据传递到DLL