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
 
3、共享库编译与运行
编译共享库:
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
 
4、cmake 指定gcc/g++的版本进行程序编译生成
 
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 共享库,开发板上编译的一些坑!的更多相关文章

  1. python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码

    python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码 淘宝IP地址库 http://ip.taobao.com/目前提供的服务包括:1. 根据用户提供的 ...

  2. ARM开发板上查看动态库或者可执行程序的依赖关系

    以ARM32开发板为例,在/lib下有一个名为ld-linux-armhf.so.3的可执行程序(在ARM64开发板上是/lib/ld-linux-aarch64.so.1),这个程序负责加载可执行程 ...

  3. 【开发实录】在鸿蒙开发板上使用websocket(移植自librws库)

    librws: Tiny, cross platform websocket client C library 相关代码可在下面下载,也可进入librws: 将librws移植到鸿蒙Hi_3861开发 ...

  4. 【Android 系统开发】 编译 Android文件系统 u-boot 内核 并烧写到 OK-6410A 开发板上

    博客地址 : http://blog.csdn.net/shulianghan/article/details/40299813  本篇文章中用到的工具源码下载 : -- ok-6410A 附带的 A ...

  5. easycwmp在开发板上的配置

    原创作品,转载请注明出处 copyright:weishusheng   2015.3.18 email:642613208@qq.com 平台: Linux version 2.6.32-279.e ...

  6. FS210开发板上Qt4.7.0移植过程

    作者:冯老师,华清远见嵌入式学院讲师. 1. 搭建Qt开发环境平台 1.开发环境:ubuntu 12.04 2.交叉编译链:arm-cortex_a8-linux-gnueabi 3.开发板:FS21 ...

  7. 开发板上使用core文件调试

    转载:http://www.nginx.cn/1521.html 如果开发板的操作系统也是linux,core调试方法依然适用.如果开发板上不支持gdb,可将开发板的环境(依赖库).可执行文件和cor ...

  8. 交叉编译环境以及开发板上-/bin/sh: ./hello: not found 转载自 http://blankboy.72pines.com

    交叉编译环境以及开发板上-/bin/sh: ./hello: not found 目标板是S3C2440.至于交叉编译环境的搭建就不多说了,网上很多教程. 搭建好了交叉编译环境后,第一件事就是传说中的 ...

  9. 02.将uboot,kernel,rootfs下载到开发板上

    转载,侵删 将uboot,kernel,rootfs下载到开发板上 1.为什么要下载 所谓下载,也称烧录,部署. 1.1.什么是u-boot Hi3518EV200 单板的 Bootloader 采用 ...

随机推荐

  1. vi命令(待更新)

    第一部分: 0:光标到本行行首$:光标到本行行尾 ^:本行第一个非blank的位置g_:本行最后一个非blank的位置 a:光标后插入(insert是光标前插入字符)o:当前行后加入新行O:当前行钱加 ...

  2. luogu P5328 [ZJOI2019]浙江省选

    传送门 每个人都可以看成一条直线\(y=ax+b\),所以我们要求的是每条线在整点处,上方线的数量的最小值(注意多条直线如果交于同一整点互不影响) 如果\(m=1\),其实只要求出半平面交,然后在半平 ...

  3. EasyTest-接口自动化测试平台部署上线问题记录

    平台url:   http://easytest.xyz 花巨资搞了个阿里云服务器,哈哈,有想体验指导的大佬私聊我~~~ 部署环境 云服务器:Ubuntu Server 16.04.1 LTS 64位 ...

  4. MySQL on duplicate key update 批量插入并更新已存在数据

    业务上经常存在一种现象,需要批量往表中插入多条数据,但在执行过程中,很可能因为唯一键冲突,而导致批量插入失败.因此需要事先判断哪些数据是重复的,哪些是新增的.比较常用的处理方法就是找出已存在的数据,并 ...

  5. 7.利用canvas和js画一个渐变的

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. css阴影——box-shadow

    1.语法 box-shadow: h-shadow v-shadow blur spread color inset;      box-shadow: 水平阴影  垂直阴影 模糊距离 阴影大小 阴影 ...

  7. python中的正则表达式的使用

    一.正则表达式简介 正则表达式的官方文档:https://www.runoob.com/regexp/regexp-tutorial.html 正则表达式:又称正规表示式.正规表示法.正规表达式.规则 ...

  8. RHEL6查看运行级别和grub加密阻止进入单用户模式

    1.查看当前运行级别 [root@cluster01 ~]# cat /etc/redhat-release Red Hat Enterprise Linux Server release 6.5 ( ...

  9. Linux RAID磁盘阵列

    RAID磁盘阵列 什么是RAID RAID是磁盘阵列的英文缩写,多块磁盘组成了一个组合,一起完成存储任务,就是磁盘阵列. RAID几种常用的类别(组合) RAID0:条带卷:最低磁盘个数2+,空间利用 ...

  10. 主流NoSQL数据库的分析与选择

    一因为新的数据项目的数据量级较大,因此考虑将mysql替换更高性能的数据库. 介绍一下NoSQL(不仅仅是关系型数据库)的不同种类和其擅长的业务. NoSQL的一个比较明显的特点是适用于现代大数据的存 ...