目录
环境设备:
背景现象:
1、x86下的结果输出和打印输出
2、arm下的结果输出和打印输出
原因分析:
解决措施:
环境设备:
x86的ubuntu、arm的麒麟
背景现象:
由于项目需要,需要将代码移植到arm服务器上去,在arm上执行程序提供服务。为此,将x86上的代码放在arm上编译成动态库,加载运行后发现执行的结果与x86本机上运行的结果相比有很大的差异。
相同代码执行结果如下:
1、x86下的结果输出和打印输出
规避区面元数量 m_iNumOfPolygonEvade = 1
10 ,1052649656 , 18 个
规避区面元数量 m_iNumOfPolygonEvade = 1
8 ,1052649656 , 16 个
--1979-- id=710000152
--1979-- id=710000598
规避区面元数量 m_iNumOfPolygonEvade = 1
1021 ,1052649656 , 1585 个
--1979-- id=710009417
--1979-- id=710031541
--1979-- id=710032913
--1979-- id=710034854
--1979-- id=710035658
--1979-- id=710043323
--1979-- id=710058884
--1979-- id=710058889
--1979-- id=710058899
--1979-- id=710058900
--1979-- id=710058904
--1979-- id=710060218
--1979-- id=710060227
--1979-- id=710100072
--1979-- id=710101186
2、arm下的结果输出和打印输出
规避区面元数量 m_iNumOfPolygonEvade = 1
10 ,-960636016 , 18 个
--1979-- id=710000035
--1979-- id=710000043
--1979-- id=710000044
--1979-- id=710000141
--1979-- id=710000158
--1979-- id=710000187
规避区面元数量 m_iNumOfPolygonEvade = 1
8 ,-960636016 , 16 个
--1979-- id=710000135
--1979-- id=710000152
--1979-- id=710000572
--1979-- id=710000596
--1979-- id=710000598
--1979-- id=710000829
--1979-- id=710000830
--1979-- id=710000932
--1979-- id=710000986
--1979-- id=710001168
--1979-- id=710001170
--1979-- id=710001171
--1979-- id=710001172
--1979-- id=710001173
--1979-- id=710001174
--1979-- id=710002033
规避区面元数量 m_iNumOfPolygonEvade = 1
1021 ,-960636016 , 1585 个
以下的--1979-- id=710000156太多了,这里省略。
原因分析:
根据上面打印可以发现,每次获取的基本数据是一样的,问题就是id保留的不一样,此处是判断点是否在面上的函数过滤出来的id号。为此重点查看该函数,算法逻辑没问题,发现函数里面采用char类型来定义的。再检索发现也有很多人遇到过ARM平台char类型导致异常的问题。
char变量在不同CPU架构下默认符号不一致,在x86架构下为signed char,在ARM64平台为unsigned char,移植时需要指定char变量为signed char。
参考ARM下char类型符号问题_强制指定char带符号_huojianying123456的博客-CSDN博客进行测试,可以根据打印充分验证上述原因的正确性。
另外参考:解决编译-fsigned-char问题-云社区-华为云 (huaweicloud.com)给出具体的解决措施。
解决措施:
直接指定arm系统的char变量(这样建议在docker中操作,方便编译和使用)
1.使用command -v gcc命令寻找gcc所在路径(一般位于/usr/bin/gcc)
2.更改gcc的名字(比如改成gcc-impl)
3.在gcc所在目录执行vim gcc,并填入如下内容保存:
#! /bin/sh
/usr/bin/gcc-impl -fsigned-char "$@"
4.执行chmod +x gcc给脚本添加执行权限
5.使用与1-4步相似的方法修改g++
最后,直接编译生成库执行程序即可得到与x86上相同的结果了。