将多个C ++ .lib项目转换为.dll项目时,Lua崩溃了!
今天我试图让“编辑并继续”在我的解决方案中工作,看起来是这样的:
游戏引擎.lib <- 游戏.lib <- 编辑器.exe
<- 服务器.exe
<- 客户端.exe
这样很好。但现在我想把引擎和游戏.lib变成.dll,这样我就可以使用Visual Studio C++的“编辑并继续”功能了。
所以我在里面加了一堆"__declspec(dllexport)",等等,它可以运行!
但在某些情况下会崩溃。实际上,它总是会在与释放内存有关的Lua函数中崩溃。
引擎和游戏都使用Lua,它们都有自己的静态C++接口函数。
我不确定,但我认为.dll有点像没有main函数的.exe,它们每个人都有自己的内存。因此,例如Game.dll导致Lua分配一些内存,Engine.dll再导致Lua将其释放,砰!正确吗?
有什么解决办法吗?当然Engine.dll应该负责Lua,但Game.dll应该能够通过新的静态函数扩展接口。
编辑:在我将Lua本身变为.dll后,再也没有崩溃了。在我尝试这之前,我还使用与所有其他项目相同的编译器重新编译了静态库,并且我双重检查了运行时库,它们都相同,并且我链接到了正确的调试/发布库。我仍然很好奇这里发生了什么。
祝你有愉快的一天,
Antoon
P.S.为什么我在Stackoverflow上没有对返回值的控制?
原文链接 https://stackoverflow.com/questions/3383932
也许只是我自己,但我认为你提供的信息有点少。由于你提到你的问题与模块边界之间的内存分配有关,我建议你阅读以下文章:
http://blogs.msdn.com/b/oldnewthing/archive/2006/09/15/755966.aspx
基本上,内存必须使用与分配时相同的分配器进行释放,也就是说,不要混合使用 new / free。这也意味着你不应该跨模块边界分配和释放内存,因为模块可能是使用不同设置编译的,例如,调试分配器可能不同于在发布版本中使用的分配器,或者由于使用了不同版本的运行时(不同的发布版本,不同的供应商等)也可能不同。
大多数情况下,最安全的做法是在一个单独的模块中处理内存分配,通过提供一致的接口来供项目中的每个其他模块使用。
我猜想是一个 DLL/EXE 分配了内存,而另一个尝试释放它却崩溃了。
解决方法是确保所有二进制文件都使用以下编译选项编译:
- 调试多线程 DLL (/MDd) 用于调试版本
- 发行多线程 DLL (/MD) 用于发布版本
当然,还要确保所有的 DLL/EXE 都使用相同的编译器和选项进行编译...
这是让在同一进程中的二进制文件(EXE 和 DLL)共享其内存分配器的唯一方法。
你写道:
引擎和游戏都使用Lua,并且它们都有自己的静态C++接口函数。
这就让我想到一个可能性,那就是引擎和游戏各自都静态链接到一个Lua的副本上。
如果是这样的话,那么当一个被一个副本创建的Lua状态被传递给另一个副本时,你会看到预料之中的结果。主要表现为破坏了内存状态并破坏了分配器。根本原因在于值“nil”的实现取决于Lua引擎内部某个地址。在同一进程中链接的第二个引擎副本将有一个不同的地址作为其“nil”的概念。这种方式最终会导致疯狂。
当然,如果游戏和引擎使用同一个Lua解释器副本(比如同时使用LUA51.DLL),那么我就是在说废话。
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
为什么你认为你需要对 DLL 进行编辑并继续?就我所使用的情况而言,它在可执行文件上也完美地工作。你发现有什么特定的错误导致你无法使用它吗?
DLL 没有自己的内存段,但它们可以使用自己的分配机制,这可能不兼容。请确保所有 DLL 和主程序链接到相同版本的 C 运行库(调试版或发布版、多线程或非多线程以及相同的版本号)。