如何在Lua C++模块中调用托管C++ DLL函数
解决方案:在Lua C模块中调用包装C#的C函数
我来帮你搞定这个问题——你现在的场景是C#函数被C++/CLI DLL包装,要在Lua的C++模块里调用这个包装后的函数,结合你的现有代码,我给你一步步的实现方案:
第一步:让Lua模块能找到ManagedDLL
首先,你需要让libutils项目能引用到ManagedDLL的接口:
- 把
ManagedDll.h添加到libutils项目里,或者直接在libutils.cpp顶部加上#include "ManagedDll.h" - 打开
libutils的项目设置,在链接器->输入->附加依赖项里添加ManagedDll.lib(这个文件是ManagedDLL编译后生成的),确保编译时能链接到这个库。
第二步:修改Lua模块的函数实现
接下来,你需要修正libutils.cpp里的showHello函数,正确调用包装后的C++函数,还要注意字符串内存的坑:
修改后的完整libutils.cpp代码:
#include "libutils.h" #include "lua.hpp" #include "ManagedDll.h" #include <string> LIBUTILS_API int showHello(lua_State *luaEnv) { // 先把CPP_ShowHello的结果存到局部std::string里,避免临时对象销毁导致指针失效 std::string helloMsg = CPP_ShowHello(); // 把字符串推入Lua栈,Lua会自动复制并管理这段内存 lua_pushstring(luaEnv, helloMsg.c_str()); return 1; } static const luaL_Reg libutils_funcs[] = { {"showHello", showHello}, {NULL, NULL} // 这里要注意是NULL,不是字符串"NULL",用来标记函数列表结束 }; LIBUTILS_API int luaopen_libutils(lua_State *luaEnv) { luaL_newlib(luaEnv, libutils_funcs); return 1; }
这里有两个关键细节:
- 别直接用
CPP_ShowHello().c_str()——因为CPP_ShowHello()返回的是临时std::string对象,语句结束后这个对象会被销毁,它的c_str()指针就失效了,Lua拿到的会是野指针。先存到局部变量里就没问题。 - 原来的函数列表里的
{"NULL", NULL}是错误的,必须用{NULL, NULL}来结束列表,否则Lua会读取到无效内存。
第三步:编译与测试
- 确保三个项目的编译架构一致(比如全是x64或者全是x86),不然会出现“找不到模块”或者链接错误。
- 按顺序编译:先编译C#的
libutilscore,再编译C++/CLI的ManagedDLL,最后编译Lua的libutils模块。 - 把所有需要的DLL都放到Lua运行的目录下:
libutilscore.dll、ManagedDll.dll、libutils.dll(如果是Linux系统,后缀是.so)。 - 写个Lua脚本测试:
local utils = require("libutils") print(utils.showHello()) -- 正常会输出:Hello From C Sharp.
额外要注意的点
- C++/CLI项目设置:
ManagedDLL必须开启公共语言运行时支持(项目属性->常规->公共语言运行时支持,选择"/clr"),不然根本调用不了C#代码。 - 内存安全:你原来的
MarshallString函数已经用Marshal::FreeHGlobal释放了分配的内存,这部分做得很对,别漏掉,不然会内存泄漏。 - Lua版本匹配:确保你用的
lua.hpp和Lua运行时的版本完全一致,比如都是Lua 5.4,不然会出现链接或者运行错误。
内容的提问来源于stack exchange,提问作者ArisHu
相关产品推荐
相关产品推荐

