Linux:ntohl函数不起作用

5
我有一个项目需要在Windows、Linux和VxWorks上构建。该项目在Linux和Windows上构建,但是为了在VxWorks上交叉编译,需要使用ntoh.h处理跨多个平台的字节序。Linux机器是小端字节序,但我的程序中的ntohl函数未执行交换操作。
我编写了一个测试程序,直接包含in.h,能够正确地进行交换操作。我还编写了另一个测试程序,只包含ntoh.h,也能够正确地进行交换操作。这两个测试程序都链接到lib64/libc.so.6库。
然而,在编译我的项目时,ntohl函数却未执行交换操作。我无法使用gdb命令“break ntohl”来中断ntohl函数。在构建时,我看到LITTLE ENDIAN警告(如下所示),但没有看到"SHOULDNT BE HERE"错误。
请帮忙解决。我不明白为什么会出现这个问题。
以下是ntoh.h代码:
#ifndef __ntoh__
#define __ntoh__

#include "basic_types.h"

#ifdef WIN32
    #include <winsock2.h>
#elif LINUX
    #include <netinet/in.h>

    //This is here to determine what __BYTE_ORDER is set to in netinet/in.h.
    // Not in original code 
    #if __BYTE_ORDER == __BIG_ENDIAN
    #warning BIG ENDIAN BYTE ORDER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    #endif 

    //This is here to determine what __BYTE_ORDER is set to in netinet/in.h. 
    // Not in original code
    #if __BYTE_ORDER == __LITTLE_ENDIAN
    #warning YAY LITTLE ENDIAN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    #endif 
#else

  #error SHOULDNT BE HERE     //added for debugging purposes
  #define ntohl(x)        (x)
  #define ntohs(x)        (x)
  #define htonl(x)        (x)
  #define htons(x)        (x)

#endif

#endif // __ntoh__

我的编译命令的一部分:

g++ -DDAU_PARSER -DNO_MT -DTEST_CLOCK -DLINUX  -g -Irelease/include -Irelease/include/Record_Data/ -Irelease/include/Utility -o dauParser DAU_Support_Tools/src/dau_parser.cpp DAU_Support_Tools/src/dau_parser_write_data_to_file.cpp Utility/src/Messaging/Communications/Message.cpp Utility/src/time_type.cpp Utility/src/collectable.cpp Utility/src/clist.cpp Utility/src/clock.cpp Utility/src/test_clock.cpp Utility/src/mutex.cpp Utility/src/ntoh.cpp ... 

错误是由以下行生成的:
int deadbeef = 0xDEADBEEF; 
printf("TESTING DEADBEEF %x %x\n", deadbeef, ntohl(deadbeef) ); 

这两行代码的输出结果相同。 测试 DEADBEEF deadbeef deadbeef


2
请添加实际上无法正常工作的代码。 - wRAR
1
从你的编辑中,printf("%x", 0xdeadbeef) 怎么可能输出 efbeadde?你可能需要发布一个最小示例来展示你的真实代码。 - Austin Phillips
2
你在进行交叉编译吗?如果不是,你正在哪个平台上构建,并且哪个可执行文件失败了? - Michael Foukarakis
@twalberg:已经尝试过 #elif Linux#if defined 两种方式,结果都是一样的。 - Kat
1
不要在标识符中使用双下划线,这些是为编译器保留的。请参阅https://dev59.com/KHVC5IYBdhLWcg3woSxW。 - Mark Ransom
显示剩余7条评论
1个回答

6

这两行代码的输出结果相同。测试 DEADBEEF deadbeef deadbeef

嗯,有些问题存在,但我们无法告诉你具体是什么。您需要调试此问题,因为只有您能观察到它。

从最简单的例子开始:

cat t.c; gcc t.c && ./a.out
#include <netinet/in.h>
#include <stdio.h>

int main() {
  int deadbeef = 0xDEADBEEF; 
  printf("TESTING DEADBEEF %x %x\n", deadbeef, ntohl(deadbeef));
  return 0;
}


TESTING DEADBEEF deadbeef efbeadde

这是否产生了预期的结果?

  • 否:你的工具链和头文件出现问题。
  • 是:你的工具链没问题,但是你的实际代码与示例所示的有所不同。
    通过预处理器运行你的代码:gcc -dD -E -DLINUX ntoh.cpp 并查看 ntohl 宏展开后的内容及其来源。

我猜测你的某个头文件可能出现了一些愚蠢的问题。

#undef ntohl
#define ntohl(x) (x)

这些标志正是我所需要的。我的软件调用了一个过时的 ntoh.h 文件,该文件没有包括 error SHOULD NOT BE HERELINUX 定义检查。过时的文件将 ntohl(x) 定义为 (x)!我更新了我的 makefile 以正确清除。过时的文件已被删除。 - Kat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接