700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > c++中调用c编写的动态链接库出现undefined reference to `xxx‘的解决方法

c++中调用c编写的动态链接库出现undefined reference to `xxx‘的解决方法

时间:2022-11-23 11:00:12

相关推荐

c++中调用c编写的动态链接库出现undefined reference to `xxx‘的解决方法

1 问题现象

用c语言写了个lib ,编译成了动态链接库,然后建了一个QT项目,想调用自己编写的lib里面的函数,编译的时候发现build OK,但是link的时候error,找不到lib 里面的函数。

[ 20%] Automatic MOC and UIC for target gst_player[ 20%] Built target gst_player_autogen[ 40%] Linking CXX executable gst_playerCMakeFiles/gst_player.dir/main.cpp.o: In function `main':main.cpp:(.text+0x52): undefined reference to `Start_Play(char*)'main.cpp:(.text+0x89): undefined reference to `Stop_Play()'collect2: error: ld returned 1 exit statusCMakeFiles/gst_player.dir/build.make:154: recipe for target 'gst_player' failedmake[2]: *** [gst_player] Error 1CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/gst_player.dir/all' failedmake[1]: *** [CMakeFiles/gst_player.dir/all] Error 2Makefile:83: recipe for target 'all' failedmake: *** [all] Error 2

lib的名称是mmplayer,lib的头文件里已经声明了这两个接口,QT项目中也引入了这个头文件:

int Start_Play(char *path);int Stop_Play(void);

QT项目构建方式选择了cmake,cmake中通过link_directories和include_directories直接设置库文件和头文件的地址。

include_directories(${PROJECT_SOURCE_DIR}) link_directories(${PROJECT_SOURCE_DIR})find_library (libpath mmplayer ${PROJECT_SOURCE_DIR})if (${libpath} STREQUAL "libpath-NOTFOUND")message (STATUS "required mmplayer library but not found!")else()message (STATUS "libpath library found in ${libpath}")endif()add_executable(gst_playermain.cppmainwindow.cppmainwindow.hmainwindow.ui)message(${PROJECT_SOURCE_DIR}/libs/)target_link_libraries(gst_player PRIVATE Qt5::Widgets mmplayer)

2 问题原因及解决方案

一开始以为是路径设置不对,但是find_library也可以找到这个lib,但是就是链接不到。

zhy@zhy-ThinkPad-E480:~/code/mypc/blog_code/gst_player/qt_gst_player/gst_player$ cmake ./...-- libpath library found in /home/zhy/code/mypc/blog_code/gst_player/qt_gst_player/gst_player/libs/libmmplayer.so-- Configuring done-- Generating done-- Build files have been written to: /home/zhy/code/mypc/blog_code/gst_player/qt_gst_player/gst_player

于是用c写了一个程序来调用这个lib,main.c中的内容:

#include <mediaPlayer.h>int main(){int ret = 0;char *filePath = "/software/gstreamer-sdk/data/media/sintel_cropped_multilingual.webm";ret = Start_Play(filePath);if (ret != 0){return - 1;}//play 50ssleep(50);ret = Stop_Play();if (ret != 0){return - 1;}return 0;}

make文件:

cmake_minimum_required(VERSION 3.5)project(camke_test LANGUAGES C)set(CMAKE_CXX_STANDARD 11)set(CMAKE_CXX_STANDARD_REQUIRED ON)include_directories(${PROJECT_SOURCE_DIR}) # 头文件的路径link_directories(${PROJECT_SOURCE_DIR})find_library (libpath mmplayer ${PROJECT_SOURCE_DIR})if (${libpath} STREQUAL "libpath-NOTFOUND")message (STATUS "required mmplayer library but not found!")else()message (STATUS "libpath library found in ${libpath}")endif()add_executable(camke_testmain.c)message(${PROJECT_SOURCE_DIR}/libs/)target_link_libraries(camke_test PRIVATE mmplayer)

然后编译,发现link也OK,说明了camke 里的so 链接没有问题。

zhy@zhy-ThinkPad-E480:~/code/mypc/blog_code/gst_player/cmake_test$ make[ 50%] Building C object CMakeFiles/camke_test.dir/main.c.o/home/zhy/code/mypc/blog_code/gst_player/cmake_test/main.c: In function ‘main’:/home/zhy/code/mypc/blog_code/gst_player/cmake_test/main.c:17:5: warning: implicit declaration of function ‘sleep’ [-Wimplicit-function-declaration]sleep(50);^~~~~[100%] Linking C executable camke_test[100%] Built target camke_test

折腾了一晚上,后来搜索发现是C++调用C存在混编问题,详细原因可自行在网上百度。解决方案很简单,QT中引入用c编写的lib的头文件时用extern "C"来包含。

extern "C"{#include <mediaPlayer.h>}

这样作的作用是告诉编译器,在编译C++的时候被调用的C代码仍然使用C编译选项,然后QT工程就可以顺利的编译通过了。

[ 20%] Automatic MOC and UIC for target gst_player[ 20%] Built target gst_player_autogenScanning dependencies of target gst_player[ 40%] Building CXX object CMakeFiles/gst_player.dir/main.cpp.o[ 60%] Linking CXX executable gst_player[100%] Built target gst_player

3 参考文章

/weixin_38956024/article/details/112549395

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。