【问题标题】:How do I link and built a dynamic link library correctly?如何正确链接和构建动态链接库?
【发布时间】:2012-02-20 08:23:42
【问题描述】:

我在linux中。我的 Makefile 文件是这个

main2: main.cpp
g++ -c $(LIBS) $(CFLAGS) -fPIC main.cpp
g++ -shared main.o -o main.so 

在哪里,

SDL_CFLAGS := $(shell sdl-config --cflags)
SDL_LDFLAGS := $(shell sdl-config --libs)
CC = gcc
COPTS = -g -Wall
CFLAGS = $(SDL_CFLAGS)
LIBS = -lstdc++ -lSDL $(SDL_LDFLAGS) -L/usr/X11R6/lib -lGL -lGLU

哪个运行

g++ -c -lstdc++ -lSDL -L/usr/lib -lSDL -L/usr/X11R6/lib -lGL -lGLU -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -fPIC main.cpp

g++ -shared main.o -o main.so

现在,这可以正常工作。生成 main.o 和 main.so 文件。

但是,当我尝试将 main.os 与 python ctypes 链接时

from ctypes import * import os
libtest = cdll.LoadLibrary(os.getcwd()+ '/main.so') libtest.main_loop()
libtest.main_loop()

我收到此错误

>>> libtest = cdll.LoadLibrary(os.getcwd() + '/main.so')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/ctypes/__init__.py", line 431, in LoadLibrary
    return self._dlltype(name)
  File "/usr/lib/python2.6/ctypes/__init__.py", line 353, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: /home/atomos/DF/open_gl_client/ctypes_client/main.so: undefined symbol: glEnd

我不确定我是否正确创建了链接库。如何创建可以加载的链接库?

我是否必须为从 main.cpp 导入的每个库创建一个 .o 和 .os 文件,还是自动处理?

我不明白编译器或链接器在做什么,但是它适用于没有导入的简单示例,但对于导入 opengl 库的 cpp 文件,它会给出该错误。

---- 更新---- ldd 针对 main.so 产生

ldd main.so
        linux-gate.so.1 =>  (0xb7755000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xaf625000)
        libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xaf5ff000)
        libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xaf4a4000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xaf485000)
        /lib/ld-linux.so.2 (0xb7756000)

---- 更新----

我在第二个编译步骤中运行了没有 -shared 标志的 g++ 并收到了这个错误

 g++ main.o -o main.so
main.o: In function `Texture_map_list::add_texture(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
main.cpp:(.text+0xf0fe): undefined reference to `glGenTextures'
main.cpp:(.text+0xf2ba): undefined reference to `glBindTexture'
main.cpp:(.text+0xf2d7): undefined reference to `glTexParameterf'
main.cpp:(.text+0xf2f4): undefined reference to `glTexParameterf'
main.cpp:(.text+0xf310): undefined reference to `glTexParameteri'
main.cpp:(.text+0xf32c): undefined reference to `glTexParameteri'
main.cpp:(.text+0xf365): undefined reference to `gluBuild2DMipmaps'
main.o: In function `init()':
main.cpp:(.text+0xf457): undefined reference to `SDL_Init'
main.cpp:(.text+0xf46d): undefined reference to `SDL_WM_SetCaption'
main.cpp:(.text+0xf472): undefined reference to `SDL_GetVideoInfo'
main.cpp:(.text+0xf480): undefined reference to `SDL_GetError'
main.cpp:(.text+0xf497): undefined reference to `SDL_Quit'
main.cpp:(.text+0xf4e2): undefined reference to `SDL_GL_SetAttribute'
main.cpp:(.text+0xf505): undefined reference to `SDL_SetVideoMode'
main.cpp:(.text+0xf513): undefined reference to `SDL_GetError'
main.cpp:(.text+0xf52a): undefined reference to `SDL_Quit'
main.cpp:(.text+0xf559): undefined reference to `glClearColor'
main.cpp:(.text+0xf565): undefined reference to `glEnable'
main.cpp:(.text+0xf571): undefined reference to `glMatrixMode'
main.cpp:(.text+0xf576): undefined reference to `glLoadIdentity'
main.cpp:(.text+0xf5a2): undefined reference to `gluPerspective'
main.o: In function `process_keypresses()':
main.cpp:(.text+0x10678): undefined reference to `SDL_PollEvent'
main.cpp:(.text+0x109a1): undefined reference to `SDL_PollEvent'
main.o: In function `main_loop':
main.cpp:(.text+0x10d76): undefined reference to `SDL_GetKeyState'
main.cpp:(.text+0x10d9f): undefined reference to `SDL_Quit'
main.o: In function `render()':
main.cpp:(.text+0x10e00): undefined reference to `SDL_GetMouseState'
main.cpp:(.text+0x10e90): undefined reference to `SDL_GetMouseState'
main.cpp:(.text+0x10f94): undefined reference to `glClear'
main.cpp:(.text+0x10fa0): undefined reference to `glMatrixMode'
main.cpp:(.text+0x10fa5): undefined reference to `glLoadIdentity'
main.cpp:(.text+0x11081): undefined reference to `gluLookAt'
main.cpp:(.text+0x11120): undefined reference to `glTranslatef'
main.cpp:(.text+0x1114d): undefined reference to `glRotatef'
main.cpp:(.text+0x1117a): undefined reference to `glRotatef'
main.cpp:(.text+0x1119e): undefined reference to `SDL_GL_SwapBuffers'
main.o: In function `draw_plane(float, float, float)':
main.cpp:(.text+0x111d8): undefined reference to `glColor3f'
main.cpp:(.text+0x111e4): undefined reference to `glBegin'
main.cpp:(.text+0x1120b): undefined reference to `glVertex3f'

....

【问题讨论】:

  • "构建文件" - 我想你的意思是 Makefile

标签: c++ opengl build-process ctypes


【解决方案1】:

首先,请注意,如果您不构建共享库,这将更容易调试。您正在使用 -shared 进行构建,因此在您在 Python 中动态加载库之前不会发生链接器错误。调试时关闭-shared,尝试链接时会在命令行看到错误:

g++ main.o -o main
main.o: In function `main':
main.cpp:(.text+0x1d): undefined reference to `glBegin'
main.cpp:(.text+0x22): undefined reference to `glEnd'
collect2: ld returned 1 exit status

现在的问题是您将链接器参数传递给编译器。我看到您在 Makefile 中很好地分离了 CFLAGSLIBS。好的。但是您在第一行同时传递了$(LIBS)$(CFLAGS),以构建main.o。 LIBS 在该行将被忽略,因为它们是链接标志。

在第二行,您实际上正在构建最终的可执行文件,您没有传递$(LIBS),因此该程序没有与 libGL 或任何其他库链接。

因此,简单地修复你的makefile:

main2: main.cpp
    g++ -c $(CFLAGS) -fPIC main.cpp
    g++ -shared main.o $(LIBS) -o main.so

编辑:后来我意识到在 GCC 中,你必须 always put the libraries after the object files,所以我相应地更改了 makefile 的最后一行。

【讨论】:

  • 这解决了问题。谢谢。
  • 很高兴听到。您可以勾选“已接受的答案”复选框以将其标记为已解决吗?谢谢。
  • 我点击了接受的答案框并投了赞成票。抱歉,我忘了这样做。
  • @HaltingState 嘿,不用担心。我喜欢你一年多后回来。我从中得到了一个徽章(“Enlightened”),因为你在这么多人投票后勾选了它:) 另请注意,我刚刚编辑了答案,因为我发现你需要将库放在 .o 文件之后。
【解决方案2】:

简单:

您正在将链接标志传递给对象编译步骤。

这是你需要的:

g++ -c -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT main.cpp
g++ -lstdc++ -lSDL -L/usr/lib -lSDL -L/usr/X11R6/lib -lGL -lGLU -fPIC main.o -o main

另外,您可能不想创建 so 文件,而是创建一个普通的可执行文件。

【讨论】:

  • 好吧,他确实想创建一个 so 文件,因为他正在将它导入 Python。
猜你喜欢
  • 2023-01-24
  • 2012-01-12
  • 2010-10-09
  • 1970-01-01
  • 2013-08-04
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多