python调用c++/c 共享库,开发板上编译的一些坑!
1、对于python,ctypes只能load动态库,但现在我的对象是一个静态库,而且我没有源代码,静态库在编译过程中没有加--fPIC参数,
所以我也没办法将其编译为动态库,有没有什么方法在python里可以调用静态库的函数?
答案:静态库.a 如果编译时没有加-fPIC参数,需要加上-fPIC重新编译生成,然后可以被c++/c程序引用,并编译生成共享库.so,被python调用。g++ 编译生成方式如下:
g++ -shared -fPIC -o libmyAPI.so myAPI.o g++ slamdata_for_py.cpp -shared -fPIC -o slamdata_for_py.so -std=c++ -I/opt/fp100/slam_ws/slamware_sdk_linux-aarch64-gcc4./linux-aarch64-release/include -L/opt/fp100/slam_ws/slamware_sdk_linux-aarch64-gcc4./linux-aarch64-release/lib -lstdc++ -ldl -lrt -lm -lpthread -lrpos_framework -lrpos_robotplatforms_rpslamware -lboost_atomic -lboost_atomic -lboost_date_time -lboost_regex -lboost_system -lboost_thread -lboost_filesystem -lboost_random -lbase64 -ljsoncpp -lrlelib -lcrypto -lcurl -lssl g++ testpy.cpp -fPIC -shared -o libtest.so -std=c++ g++ test.cpp -std=c++ -o test -I/opt/fp100/slam_ws/slamware_sdk_linux-aarch64-gcc4./samples/slamapipy/include -I/opt/fp100/slam_ws/slamware_sdk_linux-aarch64-gcc4./linux-aarch64-release/include -L/opt/fp100/slam_ws/slamware_sdk_linux-aarch64-gcc4./linux-aarch64-release/lib -L../ -lslamapipy -lstdc++ -ldl -lrt -lm -lpthread -lrpos_framework -lrpos_robotplatforms_rpslamware -lboost_atomic -lboost_atomic -lboost_date_time -lboost_regex -lboost_system -lboost_thread -lboost_filesystem -lboost_random -lbase64 -ljsoncpp -lrlelib -lcrypto -lcurl -lssl
2、不同编译器涉及到binutils 版本不同,在开发板上调整binutils 版本:
点击该网页http://ftp.gnu.org/gnu/binutils/ , 选择一个相应的版本xxx
wget http://ftp.gnu.org/gnu/binutils/xxx
./configure -disable-werror
make && make install
编译共享库:
gcc -o libdl_func.so -fPIC -rdynamic -shared dl_func.c
选项-fPIC指示编译器将代码编译成位置独立的代码,一般需要以程序文件共享其函数或变量给其他程序文件的代码都应该以此选项进行编译,选项-rdynamic指示编译器所编译/链接的为共享库程序文件。由于要使用外部变量,因此需要-shared选项,否则编译器会抛出错误信息:undefined reference to `name',表示不能找到name变量。
编译事例程序:
gcc -o dl_demo1 -L./ -ldl_func dl_demo1.c
选项-L./ 指示编译器在当前目录下寻找共享库文件,-ldl_func指示需要的共享库文件名为libdl_func.so。
运行:
./dl_demo1
cmake 指定gcc/g++版本 :
export CC=/usr/local/bin/gcc
export CXX=/usr/local/bin/g++
cmake /path/to/your/project
make
5、虚拟机交叉编译环境搭建:
sudo add-apt-repository ppa:linaro-maintainers/toolchain
sudo apt-get update
sudo apt-get install gcc-**version**-aarch64-linux-gnu sudo apt-cache search aarch64
查看哪些版本可以安装; sudo apt-get install gcc-4.8-aarch64-linux-gnu
安装一个gcc开头的4.8版本的支持64bit ARM linux的交叉编译工具; sudo apt-get install gcc-aarch64-linux-gnu
然后再安装一个没有版本号的gcc-aarch64-linux-gnu; sudo apt-get install g++-4.8-aarch64-linux-gnu
sudo apt-get install g++-aarch64-linux-gnu
以上步骤是安装支持ARM64位系统的交叉编译工具,
安装之后,用aarch64-linux-gnu-gcc -v可以查看里边的版本信息,里边有host是什么,target是什么。
6、.so 动态库 undefined symbol
1、首先排查,C++调用了c的库?是不是需要加上extern "c",尤其是类的动态库,需要用到工厂模式,create一个对象出来,该工厂函数需要extern "c"声明。
extern "C" CDbBase* create();
extern "C" void destroy(CDbBase* p);
--
CDbBase* create()
{return new CDbDb2;
}
void destroy(CDbBase* p)
{printf("destroy CDbDb2!\n");
delete p;
} 2、使用ldd -r xxx.so或者 nm -A xxx.so等命令,查看so有哪些符号未定义的。 3、在步骤2发现有很多未定义的符号,跟运行时undefined symbol符合,而且该符号是外部的系统的动态库里定义的,那目标就定位到自己写的动态库里,链接的过程时,是否把这些动态库给链接进来。
查找发现makefile编译动态库时,找不到链接符号也是允许编译通过的,那最好是加上限制条件,在makefile加上 -Xlinker --unresolved-symbols=ignore-in-shared-libs ,让其报错,把未定义的符号给报错出来。 4、根据makefile的报错,原来是忘了把外部动态库给 -l进来,并把动态库路径-L进来,即可。 makefile中没有指定对应的静态库
makefile 中修改实现:
HOME_TREE := ../../
#CURDIR是make的内嵌变量,自动设置为当前目彿 notdir -Xlinker --unresolved-symbols=ignore-in-shared-libs -shared -fPIC
MODULE_NAME := $(notdir $(CURDIR)) #CC = aarch64-linux-gnu-gcc
#CXX = aarch64-linux-gnu-g++ CC = gcc
CXX = g++ OBJS := slamdata_for_py.o houghlines.o
SRCS =
CXXSRC := src/slamdata_for_py.cpp src/houghlines.cpp
INCLUDE := -I./include -I. -I$(HOME_TREE)/linux-aarch64-release/include INCLUDE += $(shell pkg-config --cflags opencv)
OPENCV_LIBS = $(shell pkg-config --libs opencv) CFLAGS = -Wall -g -O -fPIC ###需要加-fPIC
CXXFLAGS = -std=c++ -shared -fPIC -Xlinker --unresolved-symbols=ignore-in-shared-libs #LDFLAGS := -static
LD_LIBS = -Xlinker "-(" \
-lstdc++ -ldl -lrt -lm -lpthread \
-lrpos_framework -lrpos_robotplatforms_rpslamware \
-lboost_atomic \
-lboost_chrono \
-lboost_date_time \
-lboost_regex \
-lboost_system \
-lboost_thread \
-lboost_filesystem \
-lboost_random \
-lbase64 \
-ljsoncpp \
-lrlelib \
-lcrypto \
-lcurl \
-lssl \
-Xlinker "-)" \ LDFLAGS += -L$(HOME_TREE)/linux-aarch64-release/lib $(LD_LIBS) $(OPENCV_LIBS) TARGET = libslamapipy.so
LIBPATH = ./libs/ vpath %.h ./include $(HOME_TREE)/linux-aarch64-release/include all:$(TARGET) $(OBJS):$(CXXSRC)
$(CXX) -std=c++ $(INCLUDE) -c -fPIC $^ $(TARGET):$(OBJS)
$(CXX) $(CXXFLAGS) $(OBJS) -o $(TARGET) $(LDFLAGS) clean:
rm -f *.o
rm -f *.so
rm -f $(LIBPATH)*
生成.so共享库一定不要静态链接(makefile 红字部分)。-Xlinker 可以解决库库之间相互依赖顺序问题。
python调用c++/c 共享库,开发板上编译的一些坑!的更多相关文章
- python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码
python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码 淘宝IP地址库 http://ip.taobao.com/目前提供的服务包括:1. 根据用户提供的 ...
- ARM开发板上查看动态库或者可执行程序的依赖关系
以ARM32开发板为例,在/lib下有一个名为ld-linux-armhf.so.3的可执行程序(在ARM64开发板上是/lib/ld-linux-aarch64.so.1),这个程序负责加载可执行程 ...
- 【开发实录】在鸿蒙开发板上使用websocket(移植自librws库)
librws: Tiny, cross platform websocket client C library 相关代码可在下面下载,也可进入librws: 将librws移植到鸿蒙Hi_3861开发 ...
- 【Android 系统开发】 编译 Android文件系统 u-boot 内核 并烧写到 OK-6410A 开发板上
博客地址 : http://blog.csdn.net/shulianghan/article/details/40299813 本篇文章中用到的工具源码下载 : -- ok-6410A 附带的 A ...
- easycwmp在开发板上的配置
原创作品,转载请注明出处 copyright:weishusheng 2015.3.18 email:642613208@qq.com 平台: Linux version 2.6.32-279.e ...
- FS210开发板上Qt4.7.0移植过程
作者:冯老师,华清远见嵌入式学院讲师. 1. 搭建Qt开发环境平台 1.开发环境:ubuntu 12.04 2.交叉编译链:arm-cortex_a8-linux-gnueabi 3.开发板:FS21 ...
- 开发板上使用core文件调试
转载:http://www.nginx.cn/1521.html 如果开发板的操作系统也是linux,core调试方法依然适用.如果开发板上不支持gdb,可将开发板的环境(依赖库).可执行文件和cor ...
- 交叉编译环境以及开发板上-/bin/sh: ./hello: not found 转载自 http://blankboy.72pines.com
交叉编译环境以及开发板上-/bin/sh: ./hello: not found 目标板是S3C2440.至于交叉编译环境的搭建就不多说了,网上很多教程. 搭建好了交叉编译环境后,第一件事就是传说中的 ...
- 02.将uboot,kernel,rootfs下载到开发板上
转载,侵删 将uboot,kernel,rootfs下载到开发板上 1.为什么要下载 所谓下载,也称烧录,部署. 1.1.什么是u-boot Hi3518EV200 单板的 Bootloader 采用 ...
随机推荐
- java CAS和AQS
全面了解Java中的CAS机制 https://www.jb51.net/article/125232.htm https://www.cnblogs.com/javalyy/p/8882172.ht ...
- vue.js(4)--字符串跑马灯
制作一个字符串的跑马灯效果 (1)实例代码 <!DOCTYPE html> <html lang="en"> <head> <meta c ...
- 在vue的js文件引入自定义js文件
自定义js var provinces=[] export default provinces vue页面js引入 import riskLeft from "./index.js" ...
- 利用ARouter实现组件间通信,解决子模块调用主模块问题
如果你还没使用过ARouter请你按照这篇下面博客尝试使用下然后再往下看组件通信的内容(不然的话可能会懵逼)Android Studio接入ARouter以及简单使用 如果你使用过ARouter请继续 ...
- 为Xcode配置Git和Github
Xcode.Git和Github是三个伟大的编程工具.本文记录一下如何在Xcode中使用Git作为源代码控制工具,以及如何将本地的Git仓库和远程Github上的仓库集成起来. 1. 如何为新建的Xc ...
- Python杂章
IDLE常用的快捷键: Ctrl+]:缩进代码 Ctrl+[:取消缩进 Alt+3:注释代码 Alt+4:去掉注释 F5:运行代码 Ctrl+Z:撤销一步 print('你好,Python!')
- 遍历获取html页面所有元素的id
因为要写一个权限管理系统精确到每个标签.以前用过的是给每个标签加权限判断的代码.但感觉这种方式太麻烦和落后,向让页面加载时自动把每个标签的id扫描到并保存到数据库.通过id控制.研究了下实现代码如下: ...
- Linux日常之命令sort
素材借鉴:https://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html 命令sort 是Linux中常用的排序命令,属于管道命令. 常 ...
- idea 添加静态注释和live Templates
静态注释 /** * @Description * @Author wzz * @Date ${DATE} ${TIME} */ Live Templates 1.新建一个自己的添加组如图:Mygro ...
- Codeforces Round #593 (Div. 2) C. Labs A. Stones
题目:https://codeforces.com/contest/1236/problem/A 思路:两种操作收益都是3 且都会消耗b 操作2对b消耗较小 则可优先选择操作2 再进行操作1 即可得到 ...