SPURSGO的个人博客分享 http://blog.sciencenet.cn/u/SPURSGO

博文

基于VS的RTKLIB编译学习过程及经验分享(二)

已有 1641 次阅读 2018-9-30 16:41 |个人分类:RTKLIB|系统分类:科研笔记

 

学习rtklib时,作者在manual中说过,可以用gcc重建CUI程序。因此选择Visual Studio来重建,VSC++ Builder好用,且网上的资源也多得多。

1. 首先vs2013新建一个win32dll项目取消预编译头,rtklibsrc源码放到工程路径下(注意不是工程组所在路径),如E:\Projects\rtklib-rebuild\src

2. 在项目上添加一个文件夹rtklibsrc然后在文件夹上【添加现有项目】把src中另外的源文件下文件加入工程。在rtklib-rebuild下建立rcv文件夹把原src\rcv下面的文件也添加到工程。创建的工程如下图所示:

                                              1.png

 

然后我们尝试执行编译

首次编译会与很多错误,我第一次编译时提示了大量的:无法打开包括文件:“rtklib.h”的错误,这是因为没有将rtklib.h头文件的目录包含在项目里的缘故。

解决思路就是将以下路径加入到include目录下(在项目上右键->配置属性->VC++目录->包含目录Include Path选择rtklib.h所在的目录即可)。

 

再次编译,上述错误不再提示。但还存在以下三个错误:

2.png

 

首先是一个这样的错误:

error C2466: 不能分配常量大小为0的数组    x:\xxxx\rtklibhelper\rtklibsrc\rinex.c

 

这个错误我们来看一下, [MAXPRNGLO]上面按F12,看他的定义处。

3.png

这个常量为0,那么不能进行编译,我们需要在预编译器里面加入 ENAGLO

 

网上的教程是:项目上右键->c/c++  ->预处理器->添加ENAGLO

 

再次编译发现上述问题确实消失了。但是会出现以下新的问题。。。。。。

4.png

 

error LNK2019: 无法解析的外部符号 _settspan,该符号在函数 _postpos 中被引用    x:\xxxx\ xxxx \postpos.obj  

 error LNK2019: 无法解析的外部符号 _showmsg,该符号在函数 _convrnx 中被引用    x:\xxxx\ xxxx \convrnx.obj

error LNK2019: 无法解析的外部符号 __imp__timeGetTime@0,该符号在函数_tickget 中被引用   x:\xxxx\ xxxx \rtkcmn.obj   

error LNK2019: 无法解析的外部符号 __imp__accept@12,该符号在函数 _accept_nb 中被引用    x:\xxxx\ xxxx \stream.obj 

 

解决思路可通过在添加附加库[连接器->输入->附加依赖库]添加winmm.lib, ws2_32.lib ;在预处理器里面加入DLL,来解决此问题。

 

 

最终其预编译器定义中应包含:

Win32

_CRT_SECURE_NO_WARNINGS 
_WINSOCK_DEPRECATED_NO_WARNINGS 
ENAGLO 
DLL

但我尝试上述方法问题并没有得到解决。。。。。。

另有网友指出:

1预编译器定义的问题。

RTKLIB中为了适应不同的应用需求,定义了诸多的宏,常见的包括ENAGLOENACMP _CRT_SECURE_NO_WARNINGS_WINSOCK_DEPRECATED_NO_WARNINGS等。这些预编译器定义存在的根本目的是为了控制代码编译的走向,以确保功能的实现,为此我们需要详细了解各个宏定义的存在的目的。例如,_CRT_SECURE_NO_WARNINGS存在的目的是确保strcmpVS认为不安全的函数的有效执行。_WINSOCK_DEPRECATED_NO_WARNINGS存在的目的是确保通信sock函数的有效执行。ENAGLOENACMPWIN_DLLTRACE存在的目的是确保与GLONASS、与北斗、与windows动态库编译、与TRACE信息输出相关的函数的有效执行。通过合理的预编译器定义,我们可以得到不同功能的RTKLIB动态库。

2附加依赖项的问题

前一个作者为了规避"找不到error LNK2019: 无法解析的外部符号…"的问题,选择了在添加附加库[连接器->输入->附加依赖库]中添加winmm.lib, ws2_32.lib。虽然可以解决问题,但是不够直观,很容易被其他开发人员忽略。此作者认为直接在头文件代码中添加#pragma comment(lib, "winmm.lib")#pragma comment(lib, "ws2_32.lib")更为直观明了,一劳永逸。

 

但我尝试之后还是不行。。。。。。

 

https://www.cnblogs.com/DKSoft/p/4677381.html

这篇文章目的在于将rtklib中的源码封装为dll用来供其他C程序调用,不知道与我们创建c++控制台项目或者其他win32项目的结果有什么区别。按照几篇相似文章的介绍,error LNK2019: 无法解析的外部符号问题一直无法解决,可能是我没有创建dll项目的原因。

 

上述调试都是基于将rtklib源码封装为一个动态库供调用。无问题后有作者基于这个库写了段小的调用程序:

在完成了RTKLIB动态库编译后,利用动态库可构建简单的RTCM数据读取的DemoDemo程序读取保存的实时RTCM观测信息并输出观测值文件、导航文件以及TRACE日志信息。Demo代码如下:

 

 1 #include "rtklib.h"

 2 int main()

 3 {

 4     char ifile[1024] = "C:xxx.rtcm";    

 5     char ofile[9][1024] = { "", "", "", "", "", "", "", "" };

 6     char *pofile[9] = { "" };

 7     char tracefile[1024] = "";

 8     int format = STRFMT_RTCM3;

 9  

10     double ep_rtcm[6] = { 2017, 9, 4, 14, 00, 00 };    

11     gtime_t time_rtcm = epoch2time(ep_rtcm);    

12     

13     rnxopt_t opt = { 0 };    

14     opt.tint = 0.00;

15     opt.tunit = 86400;

16     opt.rnxver = 3.02;

17     opt.navsys = 37;

18     opt.obstype = OBSTYPE_ALL;

19     opt.freqtype = 0x03;

20     opt.scanobs = 1;

21     opt.outiono = 1;

22     opt.outtime = 1;

23     opt.trtcm = time_rtcm;

24  

25     strcpy(ofile[0], ifile);

26     strcat(ofile[0], ".obs");

27  

28     strcpy(ofile[1], ifile);

29     strcat(ofile[1], ".nav");

30  

31     strcpy(tracefile, ifile);

32     strcat(tracefile, ".trace");

33     traceopen(tracefile);

34     tracelevel(5);     

35     for (int i = 0; i < 9; i++) {

36         pofile[i] = malloc(sizeof(char) * 1024);

37         memcpy(pofile[i], &ofile[i], 1024);

38     }    

39     if (convrnx(format, &opt, ifile, pofile)) printf("\n数据转换成功!\n");    

40     traceclose();

41     getchar();

42     return 0;

43 }

 

 

 

在调试Demo过程中,笔者发现RTKLIB库仍存在两个问题:

1)添加TRACE预编译器定义后,软件运行到scan_obstype函数的trace(3,"scan_obstype: nf=%s, opt=%s\n",nf,opt)语句时会提示内存出错,调试后发现该语句中nf的输出类型出错,应将"%s"更改为"%d",即trace(3,"scan_obstype: nf=%d, opt=%s\n",nf,opt)。这反映了RTKLIB原始编码系统环境与VS IDE的差异,后续应用库文件时需要多加注意。

2convrnx函数在执行完成退出动态库回到主函数main时,Debug模式下会弹出"Run-Time Check Failure #2 - Stack around the variable 'opt_' was corrupted."异常。Release模式下不弹出该异常。网络上关于该异常主体上认为时由于内存越界造成的,笔者暂未找出opt_变量越界的原因,后续会做深入研究。该异常的最快捷的解决方案时将"project->配置属性->c/c++->代码生成->基本运行时检查"改为"默认值"即可。




http://blog.sciencenet.cn/blog-3386358-1138018.html

上一篇:基于VS的RTKLIB编译学习过程及经验分享(一)
下一篇:基于VS的RTKLIB编译学习过程及经验分享(三)

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备14006957 )

GMT+8, 2019-10-19 09:33

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部