使用共享 dll 和最少的 C++/SWIG/Lua 代码出现链接错误

发布于 2024-12-07 19:52:47 字数 2609 浏览 1 评论 0原文

这是一个非常具体的编译问题,涉及 C++、SWIG 和 Lua。

我有一个非常简单的基本代码:

[AClass.hpp]

class AClass {
public:
    AClass();
};

[AClass.cpp]

#include "AClass.hpp"

AClass::AClass() {}

[main.cpp]

#include "AClass.hpp"

int main() {
    AClass my_a;
}

此时,有与编译无关。 我首先在 libengine.dll 中编译该类,然后使用共享库来构建可执行文件。

让我们引入一个 SWIG 模块,并将其添加到 dll 中:

[AClass.i]

%module M_AClass

%{
#include "AClass.hpp"
%}

%include "AClass.hpp"

因此,当链接可执行文件中的所有内容时,我收到以下错误:

g++ -c main.cpp
g++ -c AClass.cpp
swig.exe -c++ -lua AClass.i
g++ -Iinclude -c AClass_wrap.cxx
g++ AClass.o AClass_wrap.o -shared -o libengine.dll -Wl,--out-implib,libengine.dll.a -L. -llua5.1
Creating library file: libengine.dll.a
g++ main.o libengine.dll.a -o main.exe
main.o:main.cpp:(.text+0x16): undefined reference to `AClass::AClass()'
collect2: ld returned 1 exit status

有人有线索吗?我尝试使用 nm 查看 dll,但我无法弄清楚如何向共享库添加另一个 .o 可以“隐藏”一个方法(这不是特定于构造函数)。


为了重现上下文,以下是放置在目录中以构建测试的必要文件:

include/ # Contains "lauxlib.h", "lua.h" & "luaconf.h"
liblua5.1.dll
AClass.hpp
AClass.cpp
AClass.i
main.cpp
Makefile

最后,这里是 Makefile 内容:

ifneq (,$(findstring Linux,$(shell uname -o)))
    EXEC := main
    LIB := libengine.so
    LIB_FLAGS := -o $(LIB)
else
    EXEC := main.exe
    LIB := libengine.dll.a
    LIB_FLAGS := -o libengine.dll -Wl,--out-implib,$(LIB)
    #NO DIFFERENCE using ".dll.a" as in CMake (option: -Wl,--out-implib,) or only ".dll"

    ifdef SystemRoot
    # Pure Windows, no Cygwin
        RM := del /Q
    endif
endif

LANG_LIB := -L. -llua5.1
LANG_INC := include
LANG_SWIG := -lua

all: clean $(EXEC)

clean:
    $(RM) main *.exe *_wrap.cxx *.o libengine.*

$(EXEC): main.o $(LIB)
    g++ $^ -o $@

main.o: main.cpp
    g++ -c $<

#NO PB without dependency to AClass_wrap.o
$(LIB): AClass.o AClass_wrap.o
    g++ $^ -shared $(LANG_LIB) $(LIB_FLAGS)

AClass.o: AClass.cpp
    g++ -fPIC -c $<

AClass_wrap.o: AClass_wrap.cxx
    g++ -fPIC -I$(LANG_INC) -c $<

AClass_wrap.cxx: AClass.i
    swig -c++ $(LANG_SWIG) $<

这是在 Windows 7 下使用 MingGW g++ v4.5.2、SWIG 2.0.2 和 Lua5 进行测试的。 1.

编辑:当 SWIG 导出到 tcl 时也会出现此问题。不过在Linux下编译绝对没有问题。我比较了生成的AClass_wrap.cxx,它们是相似的。

This is a really specific compilation problem involving C++, SWIG and Lua.

I have a really simple base code :

[AClass.hpp]

class AClass {
public:
    AClass();
};

[AClass.cpp]

#include "AClass.hpp"

AClass::AClass() {}

[main.cpp]

#include "AClass.hpp"

int main() {
    AClass my_a;
}

At this point, there is no matter with compilation.
I first compile the class in libengine.dll and then use the shared library to build the executable.

Let's introduce a SWIG module, and add it to the dll :

[AClass.i]

%module M_AClass

%{
#include "AClass.hpp"
%}

%include "AClass.hpp"

Henceforth, when linking everything in an executable, I got the following error :

g++ -c main.cpp
g++ -c AClass.cpp
swig.exe -c++ -lua AClass.i
g++ -Iinclude -c AClass_wrap.cxx
g++ AClass.o AClass_wrap.o -shared -o libengine.dll -Wl,--out-implib,libengine.dll.a -L. -llua5.1
Creating library file: libengine.dll.a
g++ main.o libengine.dll.a -o main.exe
main.o:main.cpp:(.text+0x16): undefined reference to `AClass::AClass()'
collect2: ld returned 1 exit status

Would anyone have a clue ? I tried looking into the dll with nm but I can't figure how adding another .o to the shared library can "hide" a method (this isn't specific to constructors).


To reproduce the context, here are the necessary files to put in a directory to build the test :

include/ # Contains "lauxlib.h", "lua.h" & "luaconf.h"
liblua5.1.dll
AClass.hpp
AClass.cpp
AClass.i
main.cpp
Makefile

And finally, here is the Makefile content :

ifneq (,$(findstring Linux,$(shell uname -o)))
    EXEC := main
    LIB := libengine.so
    LIB_FLAGS := -o $(LIB)
else
    EXEC := main.exe
    LIB := libengine.dll.a
    LIB_FLAGS := -o libengine.dll -Wl,--out-implib,$(LIB)
    #NO DIFFERENCE using ".dll.a" as in CMake (option: -Wl,--out-implib,) or only ".dll"

    ifdef SystemRoot
    # Pure Windows, no Cygwin
        RM := del /Q
    endif
endif

LANG_LIB := -L. -llua5.1
LANG_INC := include
LANG_SWIG := -lua

all: clean $(EXEC)

clean:
    $(RM) main *.exe *_wrap.cxx *.o libengine.*

$(EXEC): main.o $(LIB)
    g++ $^ -o $@

main.o: main.cpp
    g++ -c 
lt;

#NO PB without dependency to AClass_wrap.o
$(LIB): AClass.o AClass_wrap.o
    g++ $^ -shared $(LANG_LIB) $(LIB_FLAGS)

AClass.o: AClass.cpp
    g++ -fPIC -c 
lt;

AClass_wrap.o: AClass_wrap.cxx
    g++ -fPIC -I$(LANG_INC) -c 
lt;

AClass_wrap.cxx: AClass.i
    swig -c++ $(LANG_SWIG) 
lt;

This was tested under Windows Seven, with MingGW g++ v4.5.2, SWIG 2.0.2 and Lua5.1.

EDIT: The problem also appear when SWIG-exporting to tcl. However, there is absolutely no problem compiling under Linux. I compared the generated AClass_wrap.cxx, they are similar.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

百变从容 2024-12-14 19:52:47

mingw 下的 g++ 可能需要 __declspec(dllimport/export)

g++ under mingw might require __declspec(dllimport/export)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文