Eclipse框架下rtklib动态库编译

1、前言

RTKLIB是全球导航卫星系统GNSS(global navigation satellite system)的标准&精密定位开源程序包,包含了丰富的导航定位算法应用、通信协议接口和各类函数库API,具体内容可参考笔者博文《RTKLIB编译及RTCM数据读取样例》

目前网络上流传的rtklib动态库编译博文多是基于Microsoft Visual Studio框架,这主要是由于国人习惯于使用微软Windows操作系统的缘故,而rtklib本质上是一个跨平台的导航定位库,其在Linux或Unix系统下运行更为稳健,且编译开发难度更容易。因此,笔者在Eclipse框架下对rtklib动态库编译问题进行了研究,并给出若干实用样例,供导航算法研究人员和软件研发人员参考。

2、基于Eclipse框架的rtklib编译

基于Eclipse框架的rtklib编译的第一步是搭建编译环境,笔者使用的操作系统是Ubuntu18.04桌面版,使用的IDE版本是Eclipse Oxygen.3a Release(4.7.3a),具体编译环境开发人员可根据需要做相应调整,在此不在赘述。

搭建好IDE编译环境后,即可进行代码编译工作,具体步骤如下:

(1)创建Project。在Eclipse IDE环境中新建一个C Managed Build工程,填写工程名和工程保存路径,选择项目类型和编译工具,填写工程基本信息,设定工程配置信息,如图1至图4所示。笔者在构建工程时将项目命名为rtklibdemo,选择了Hello World ANSI C Project可执行程序模板和linux GCC编译器,项目配置属性采用IDE默认属性,暂未做更改,后续根据编译需要再做相应调整。初学者可仿照处理,也可预先配置Advanced settings的相应选项。

图1 新建C Managed Build工程

图2 设置工程名、工程路径、项目类型和编译器

图3 设置项目基本信息

图4 设置项目配置信息

(2)导入rtklib源文件。rtklib源文件目前在Github上有两个分支,最新的版本分别是rtklib 2.4.3 b29版本(更新日期为2017/09/02)和rtklib 2.4.2 p13版本(更新日期为2018/01/30),其中rtklib 2.4.2版本包含PPP定位导航算法的相关源码,开发人员可根据需要自行选择。完成下载后,在Eclipse项目工程src文件夹标签下右键选择导入源文件,在弹出的界面框中选择File System,定位到rtklib源文件文件夹,选择所有的c文件,点击Finish按钮即可,如图5、6所示。

图5 配置导入资源

图6 导入rtklib源文件

(3)编译rtklib。完成源文件导入后,点击编译Eclipse IDE会提示“fatal error:rtklib.h:No such file or directory”错误,如图7所示。原因是rtklib源码中将各个厂家的数据解码函数统一存放在rcv文件夹中,与头文件rtklib不在同一文件夹,笔者采用的更正策略是将rcv文件夹中的所有c文件的#include “rtklib.h”统一更新为#include “../rtklib.h”以规避头文件路径错误的问题,如图8所示。

图7 rtklib.h头文件路径错误

图8 rtklib.h头文件路径错误解决方案

再次点击编译Eclipse IDE会提示“undefined reference to ‘tan’”等数学函数定义不存在错误,“undefined reference to ‘pthread_creat’”等线程函数定义不存在错误以及“undefined reference to ‘showmsg’”等函数不存在错误,如图9、10所示。

图9 数学函数与线程函数定义不存在错误

图10 “undefined reference to ‘showmsg’”等函数不存在错误

“数学函数定义不存在错误”是由于gcc编译器在编译时缺少libm,解决方案是在链接库中添加m库,如图11所示。

图11 “数学函数定义不存在错误”解决方案

“线程函数定义不存在错误”是由于pthread不是Linux下的默认的库,在链接的时候,无法找到phread库中哥函数的入口地址,链接失败。解决方案是在gcc编译是添加-lpthread参数,具体到Eclipse IDE即在GCC C Compiler的Miscellaneous选项卡和GCC C Linker的General选项卡中勾选“Support for pthread (-lpthread)”选项,如图12、13所示。

图12 GCC C Compiler -lpthread参数配置

图13 GCC C Linker -lpthread参数配置

“undefined reference to ‘showmsg’”等函数不存在错误是由于在编译前没有预定义“DLL”标识,从而导致函数无法正常编译。解决方案是在GCC C Compiler的Preprocessor选型卡中的Defined symbols中添加DLL预定义标识,如图14所示。(注:后续可采用类似的操作预定义ENAGLO、ENACMP、TRACE等调整rtklib库的功能范围。)

图14 “undefined reference to ‘showmsg’”等函数不存在错误解决方案

再次点击编译Eclipse IDE会提示编译成功,表明rtklib动态库编译基本完成,可在此基础上调用相关接口。

3、应用实例

完成了Eclipse IDE环境下rtklib编译后,笔者调用了rtklib中封装的串口通信的接口函数,实现了简单的串口数据通信功能,代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include "rtklib.h"
 4
 5 int main(void) {
 6     int opt[8] = { 10000, 10000, 1000, 32768, 10, 1000, 30, 0 };
 7     int strs[1] = { STR_SERIAL };
 8     double nemapos[3] = { 0 };
 9     char *path[8],*cmd[4]={0},*cmds_p[4]={0};
10     strconv_t *conv[4] = { 0 };
11
12     strsvr_t *svr = (strsvr_t *)malloc(sizeof(strsvr_t));
13     for (int i = 0; i < 1; i++)
14         path[i] = (char*)malloc(sizeof(char) * 1024);
15
16     printf("please input the device name:");
17     scanf("%s",path[0]);
18
19     strsvrinit(svr, 0);
20     strsvrstart(svr, opt, strs, path, conv, cmd, cmds_p, nemapos);
21
22     unsigned int npb0 = 0;
23     while(1)
24     {
25         strlock(&svr->stream[0]);
26         for (unsigned int i = 0; i < svr->stream[0].inb - npb0; i++)
27         {
28             printf("%c", svr->buff[i]);
29         }
30         if (npb0 < svr->stream[0].inb){
31             npb0 = svr->stream[0].inb;
32         }
33
34         strunlock(&svr->stream[0]);
35         sleepms(1);
36     }
37     return EXIT_SUCCESS;
38 }

原文地址:https://www.cnblogs.com/whugreyhound/p/9262534.html

时间: 2024-08-24 09:02:06

Eclipse框架下rtklib动态库编译的相关文章

Windows下64位SQLite3.10动态库编译

在开始动手编译之前,先让我们对SQLite有一个初步的认识: SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中.它是D.RichardHipp建立的公有领域项目.它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了.它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl.C#.PHP.Java等,还有ODBC接口,同样

C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

目录 0. 引言 1. 交叉编译 2. Cygwin简介 3. 静态库编译及使用 4. 动态库编译及使用 5. MinGW简介 6. CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件并且支付可观费用才能够被授权使用的一个操作系统.linux是unix的克隆版本,是由其创始人Linus和诸多世界知名的黑客手工打造的一个操作系统.为什么linux和unix之间有很多软件可以很轻松的移植?因为linux也满足POSIX规范,所以在运行机制上跟unix相近.同时,POSI

如何使用Eclipse的NDK开发动态库,静态库

============问题描述============ 如何使用Eclipse的NDK开发动态库,静态库? Eclipse中已经安装了NDK,CDT和Esequoyah并配置(是在网上查的). 我是做C++的,公司业务需要自学Android,对Java也是知道一点皮毛. 在网上查了一些资料,我都没有成功做出最简单的动态库或静态库,郁闷啊! 有没有详细指导? ============解决方案1============ 你去搜一下Android的jni开发,就知道了,一点都不难,不过一般开发ndk

gcc静态动态库编译

centos5.8,g++4.1.2 最近操作比较多,小小笔记下 静态库,动态库编译和链接 //1.DynamicMath.h class DynamicMath{ public: static double add(double a, double b); static double sub(double a, double b); void print();}; //2.DynamicMath.cpp #include "DynamicMath.h"#include <ios

[转]vs2010 静态库以及动态库编译实例

转载地址:http://blog.csdn.net/wswxfwps/article/details/31788703 有网友留言,指出了本文中有错的地方,在此谢谢指摘. 重新编辑了一下本文,新添加了一些东西以及到目前为止对静态库和动态库的心得理解和心得,和大家分享 最近在研究ffmpeg,由于用c#开发,而ffmpeg采用的是c开发,因此打算先用c将ffmpeg的一些函数封装成库,在用c#来调用,花了一天时间(确实水平太低)写了几个vs2010下的静态库以及动态库的编译实例. 一.vs2010

linux下so动态库一些不为人知的秘密

linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名.二者都使用广泛.本文主要讲动态库方面知识.    基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些动态库,使用ldd命令查看 # ldd /bin/ls linux-vdso.so.1 => (0x00007fff597ff000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00000036c2e00000) librt.so.1 => /

Linux 环境下 gcc 链接库 编译、链接(概览) 以及 自动化工具Makefile的编写

个人博客首页(点击查看详情) -- https://blog.51cto.com/11495268 1.简介    程序编译一般需要经预处理.编译.汇编和链接,在实际应用中,有些公共代码需要反复使用,就把这些代码编译成为 "库" 文件,本文 主要 描述 Linux 平台下 库文件的 创建 和 链接 相关操作(既然都看 这么底层的内容了,相信 也有一定的基础,所以本文 对相关命令 也不会进行详细解释)    备注:    linux平台下,静态链接库是以 .a 的后缀文件,动态链接库是以

Linux下的动态库与静态库

2019-09-25 关键字:生成库.静态库引用.动态库引用 在 C 开发中,“库”是一个经常听到的名词. 所谓的库其实就是一个二进制文件.这个二进制文件的内容是可被其它C程序调用执行的函数.换句话说,库就是一组C代码的打包形式而已,打包是指将源代码以库的形式编译而生成的文件. 不过即使它只是源代码的打包,它也仍然是有系统专有性的,即不同系统下编译出来的库并不能互相兼容使用. C库可分为动态库与静态库两种.引用了外部库的应用程序在编译时会在”链接期“处理库与程序源码之间的关系. 1.静态库 静态

linux下so动态库一些不为人知的秘密(转)

linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名.二者都使用广泛.本文主要讲动态库方面知识.基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些动态库,使用ldd命令查看 # ldd /bin/ls 使用 ldd -u /bin/ls 查看不需要链接的so 大家知不知道linux从程序(program或对象)变成进程(process或进程),要经过哪些步骤呢,这里如果详细的说,估计要另开一篇文章.简单的说分三步:    1.fork进程,在内核创建