MSVC 名称修改
MSVC name mangling
我正在尝试使用 MSVC 2015 x86 构建 Lua 和 QtLua,但我遇到了 exported/imported 符号的问题。
以下是我为构建 Lua 5.3.2 (source) 所做的工作:
cl /MD /O2 /c /DLUA_BUILD_AS_DLL *.c
ren lua.obj lua.o
ren luac.obj luac.o
link /DLL /IMPLIB:lua5.3.2.lib /OUT:lua5.3.2.dll *.obj
link /OUT:lua.exe lua.o lua5.3.2.lib
lib /OUT:lua5.3.2-static.lib *.obj
link /OUT:luac.exe luac.o lua5.3.2-static.lib
到目前为止一切正常,dependancy walker 显示函数导出时没有任何修改。
然后我使用 cmake 构建 QtLua,我遇到了大约 100 个错误,例如:
error LNK2019: unresolved external symbol _lua_close referenced in function "public: virtual __thiscall QtLua::State::~State(void)" (??1State@QtLua@@UAE@XZ)
所以基本上我的问题是 DLL 导出 lua_close
并且链接器查找 _lua_close
.
经过一些搜索,_lua_close
格式似乎是合法的,因为 Microsoft 文档指出使用 __cdecl
调用的 C 符号被“_”前缀破坏。
但是我不明白为什么 DLL 会导出未损坏的名称。
在Lua(C 文件)中编译时的函数声明
__declspec(dllexport) void (lua_close) (lua_State *L);
在 Qt 中编译时的函数声明Lua(C++ 文件)
extern "C" {
extern void (lua_close) (lua_State *L);
}
快速回答
MSVC 没有找到 lua DLL(或库)。
长答案
使用 __cdecl
调用的导出 C 函数未被破坏,而使用 __cdecl
调用的内部 C 函数被破坏并带有“_”前缀。
来源:http://wyw.dcweb.cn/stdcall.htm
为了解决我的问题,我从 QtLua 中获取了所有源文件并从中创建了一个 qmake 项目。还有塔达!有用! (好吧,这不是因为 QtLua 似乎没有在 gcc 以外的任何东西上进行测试,但我摆脱了这个链接器问题)。
我的结论是:
- MSVC 抱怨没有找到
_function
,实际上正在寻找 function
(或者可能两者都有)。
- CMake,即使它在配置时找到了 lua 库,也未能在构建时将正确的选项传递给链接器。
我正在尝试使用 MSVC 2015 x86 构建 Lua 和 QtLua,但我遇到了 exported/imported 符号的问题。
以下是我为构建 Lua 5.3.2 (source) 所做的工作:
cl /MD /O2 /c /DLUA_BUILD_AS_DLL *.c
ren lua.obj lua.o
ren luac.obj luac.o
link /DLL /IMPLIB:lua5.3.2.lib /OUT:lua5.3.2.dll *.obj
link /OUT:lua.exe lua.o lua5.3.2.lib
lib /OUT:lua5.3.2-static.lib *.obj
link /OUT:luac.exe luac.o lua5.3.2-static.lib
到目前为止一切正常,dependancy walker 显示函数导出时没有任何修改。
然后我使用 cmake 构建 QtLua,我遇到了大约 100 个错误,例如:
error LNK2019: unresolved external symbol _lua_close referenced in function "public: virtual __thiscall QtLua::State::~State(void)" (??1State@QtLua@@UAE@XZ)
所以基本上我的问题是 DLL 导出 lua_close
并且链接器查找 _lua_close
.
经过一些搜索,_lua_close
格式似乎是合法的,因为 Microsoft 文档指出使用 __cdecl
调用的 C 符号被“_”前缀破坏。
但是我不明白为什么 DLL 会导出未损坏的名称。
在Lua(C 文件)中编译时的函数声明
__declspec(dllexport) void (lua_close) (lua_State *L);
在 Qt 中编译时的函数声明Lua(C++ 文件)
extern "C" {
extern void (lua_close) (lua_State *L);
}
快速回答
MSVC 没有找到 lua DLL(或库)。
长答案
使用 __cdecl
调用的导出 C 函数未被破坏,而使用 __cdecl
调用的内部 C 函数被破坏并带有“_”前缀。
来源:http://wyw.dcweb.cn/stdcall.htm
为了解决我的问题,我从 QtLua 中获取了所有源文件并从中创建了一个 qmake 项目。还有塔达!有用! (好吧,这不是因为 QtLua 似乎没有在 gcc 以外的任何东西上进行测试,但我摆脱了这个链接器问题)。
我的结论是:
- MSVC 抱怨没有找到
_function
,实际上正在寻找function
(或者可能两者都有)。 - CMake,即使它在配置时找到了 lua 库,也未能在构建时将正确的选项传递给链接器。