64位平台编译常见问题汇总(个人移植问题仅供参考)
这个问题在资料《《32位程序移植到64位平台前的准备工作 》》中有提及到。以下是文章中的内容:
涉及隐式函数声明,如果没有对代码中调用的每一个函数提供一个原型,编译器就会做出假设。编译器产生的类似警告信息"Implicit function declaration: assuming extern returning int"在32位构建时通常是无关紧要的;但在64位构建时,这种返回值是int的假设,当函数实际上是返回long或指针(例如malloc)时,就会导致真正的问题了。为了不让编译器做出这种假设,必须确保所有需要的系统头文件都包含或提供了外部函数的函数原型。
在MDS代码中所涉及到的代码段如下:
在sipCC.c文件6536行中,在调用下面函数时会出现警告信息
if (strncmp(p->route, (char *)antPickupExt(), strlen((char *)antPickupExt())))
原因:antPickupExt()返回值为char *型,并未在头文件中声明,在64为编译中函数返回值默认为int型。
修改的话,在头文件中增加函数声明。
MDS产品代码中,将整数强转成void *指针,作为参数传递给函数使用。在跨平台移植中,可能会出现问题。修改的话,直接传送整数的地址。在函数实现代码中,再进行类型强转后取其值。如下:
Int trunkId
- pthread_create(&offnet_callee_ptr->pingthread, &attr, IPTrunkSendRawPingToPeer, (void *) trunkId);
+ pthread_create(&offnet_callee_ptr->pingthread, &attr,IPTrunkSendRawPingToPeer, (void *) &trunkId);
void *IPTrunkSendRawPingToPeer(void *data)
{
- int trunkId = (int) data;
+ int trunkId = *((int*)data);
……………
}
下面是产品代码中的一个例子:
结构体定义
1
2
3
4
5
6
7
8
9
10
11
12
struct ant_translator {
char name[80];
int srcfmt;
int dstfmt;
_antTranslatorEndPt *(*new)(void);
int (*framein)(_antTranslatorEndPt *endpt, tAntFrame *in);
tAntFrame * (*frameout)(_antTranslatorEndPt *endpt);
void (*destroy)(_antTranslatorEndPt *endpt);
tAntFrame * (*sample)(void);
int cost;
struct ant_translator *next;
};
初始化:
1
2
3
4
5
6
7
8
9
static struct ant_translator g729tolin = {
"g729tolin",
ANT_FORMAT_G729A, ANT_FORMAT_SLINEAR,
g729tolin_new,
g729tolin_framein,
g729tolin_frameout,
g729_destroy,
g729tolin_sample
};
警告:从不兼容的指针类型初始化
未确定:
上面警告信息对程序有没有影响,有何影响还不确定?
如果想排除警告信息,可按照以下方法进行修改。
static struct ant_translator lintog723 = {
"lintog723",
ANT_FORMAT_SLINEAR, ANT_FORMAT_G723_1,
- lintog723_new,
- lintog723_framein,
- lintog723_frameout,
- g723_destroy,
- lintog723_sample
+ (_antTranslatorEndPt *(*)()) lintog723_new, // 返回值类型进行
+ (int (*)()) lintog723_framein,
+ (tAntFrame * (*)()) lintog723_frameout,
+ (void (*)()) g723_destroy,
+ (tAntFrame * (*)()) lintog723_sample
};
编译是出现以下警告:(在代码中大概有三处吧)
警告:传递参数 6 (属于‘recvfrom’)给指针时目标与指针有/无符号不一致。
示例:
int fromlen;
fromlen = sizeof from;
h->resp_len = recvfrom(h->fd, h->response,
MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen);
去除警告信息的话,是将 fromlen类型定义为: socklen_t 。其他如Size_t也会有警告。
1.5. 函数 inet_ntoa 使用时出现警告在编译过程中出现这种警告:'argument' : conversion from 'size_t' to 'int', possible loss of data警告:当将一个指针转换为大小不同的整数时给出警告。
inet_ntoa()返回的就是char *,如果在Linux出现上述警告,就是没有加上包含这个函数的头文件 在linux上为#include<arpa/inet.h>