关于windows下C++程序移植到linux下的一些头文件对应问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于windows下C++程序移植到linux下的一些头文件对应问题相关的知识,希望对你有一定的参考价值。

在windows下 C++程序包含了个winsock2.h头文件 那么我移植到linux下有没有什么头文件与之相对应的 如果没有 该怎么改

必须要封装osa适配层了,两者有些API有差异,靠单纯的换头文件搞不定。

比如你想同时在linux和windows上使用stat这个函数,同样是包含#include<sys/stat.h>,但是stat的结构体根本就不一样。

linux版本:

typedef struct stat



 unsigned long st_dev;  /* device ID number */

     unsigned long st_ino;  /* file serial number */

     unsigned short st_mode; /* file mode (see below) */

     short st_nlink; /* number of links to file */

     short st_uid;  /* user ID of file's owner */

     short st_gid;  /* group ID of file's group */

     unsigned long st_rdev; /* device ID, only if special file */

     unsigned long st_size; /* size of file, in bytes */

     unsigned long st_atime; /* time of last access */

     unsigned long st_mtime; /* time of last modification */

     unsigned long st_ctime; /* time of last change of file status */

     long st_blksize;

     long st_blocks;

     unsigned int st_attrib; /* file attribute byte (dosFs only) */

stat_type;

windows版本:

struct stat 

        _dev_t     st_dev;

        _ino_t     st_ino;

        unsigned short st_mode;

        short      st_nlink;

        short      st_uid;

        short      st_gid;

        _dev_t     st_rdev;

        _off_t     st_size;

        time_t st_atime;

        time_t st_mtime;

        time_t st_ctime;

        ;

参考技术A 与这几个头文件对应
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
但是函数调用方式要注意,有变化
参考技术B 在linux下, 最好还是用到函数时去man下,了解使用方法、参数,返回值等,然后在自己实现的code里添加相应的头文件即可

将数据序列化代码从 C++ linux/mac 移植到 C++ windows

【中文标题】将数据序列化代码从 C++ linux/mac 移植到 C++ windows【英文标题】:Porting data serialization code from C++ linux/mac to C++ windows 【发布时间】:2011-11-16 15:48:57 【问题描述】:

我有一个在 mac 和 linux 上编译并成功运行的软件框架。我现在正在尝试将其移植到 Windows(使用 mingw)。到目前为止,我已经在 Windows 下编译和运行了该软件,但它不可避免地存在错误。特别是,我在将 macos(或 linux)中序列化的数据读取到程序的 windows 版本(segfaults)时遇到问题。

序列化过程将原始变量(long、int、double 等)的值序列化到磁盘。

这是我正在使用的代码:

#include <iostream>
#include <fstream>

template <class T>
void serializeVariable(T var, std::ofstream &outFile)

    outFile.write (reinterpret_cast < char *>(&var),sizeof (var));


template <class T>
void readSerializedVariable(T &var, std::ifstream &inFile)

inFile.read (reinterpret_cast < char *>(&var),sizeof (var));

所以为了保存一堆变量的状态,我依次为每个变量调用serializeVariable。然后为了读回数据,以与保存数据相同的顺序调用 readSerializedVariable。例如保存:

::serializeVariable<float>(spreadx,outFile);
::serializeVariable<int>(objectDensity,outFile);
::serializeVariable<int>(popSize,outFile);

阅读:

::readSerializedVariable<float>(spreadx,inFile);
::readSerializedVariable<int>(objectDensity,inFile);
::readSerializedVariable<int>(popSize,inFile);

但在 Windows 中,这种序列化数据的读取失败。我猜windows对数据的序列化有点不同。我想知道是否有一种方法可以修改上述代码,以便可以在任何其他平台上读取保存在任何平台上的数据......有什么想法吗?

干杯,

本。

【问题讨论】:

什么是T类型?我可以为不同的编译器考虑不同的 sizeof(var) 值——例如,作为结构元素对齐的结果。想想另一种序列化机制,比如 XML。 类型是原始变量(例如,参见编辑后的帖子)..例如,我不知道编译器可以为 sizeof(long) 生成不同的值。你确定吗?我的意思是,我认为 long 总是 4 个字节,char 总是 1 个字节,独立于编译器等。 是的,绝对是,我们处理多个平台,在一些平台上 long 是 4 个字节,在一些平台上是 8 个字节。我相信标准只规定了数据类型的最小字节数,而不是确切的字节数。 既然如此,混蛋!谢谢!将按照 Alex 的建议研究 XML。刚刚确认这是问题所在:在我的 Mac 上,long 是 8 个字节,在我的 Windows 平台上,它是 4。 您可能还想研究 boost 的序列化库或 json(我认为是 libjanson),因为我发现它们的重量更轻。 【参考方案1】:

像这样的二进制序列化应该可以在这些平台上正常工作。您确实必须尊重字节顺序,但这是微不足道的。我认为这三个平台在这方面没有任何冲突。

不过,你真的不能使用松散的类型规范。 intfloatsize_t 大小都可以跨平台变化。

对于整数类型,请使用在 cstdint 标头中找到的严格大小的类型。 uint32_tint32_t 等。Windows 没有可用的 iirc 标头,但您可以改用 boost/cstdint.hpp。

浮点应该工作,因为大多数编译器都遵循相同的 IEEE 规范。

C - Serialization of the floating point numbers (floats, doubles)

二进制序列化确实需要彻底的单元测试。我强烈建议您投入时间。

【讨论】:

谢谢汤姆。我真的想弄清楚我的实施发生了什么。修复后会更新。 :-) 愚蠢地,正如 user103749 所建议的那样,由于某种原因,我在打开文件流时忘记了合并 std::ios::binary 。由于不打扰这个总是在 linux 和 mac 下工作,所以这个错误就溜走了。很高兴我坚持使用这种序列化方法。干杯。【参考方案2】:

这只是一个疯狂的猜测,我无法为您提供更多帮助。我的想法是字节顺序不同:大端与小端。因此,任何大于一个字节的内容在加载到顺序颠倒的机器上时都会被弄乱。

例如,我在 msdn 中发现了这种和平的代码:

int isLittleEndian() 
    long int testInt = 0x12345678;
    char *pMem;

    pMem = (char *) testInt;
    if (pMem[0] == 0x78)
        return(1);
    else
        return(0);

我猜你在 linux 和 windows 上会有不同的结果。最好的情况是,如果您的编译器有一个标志选项可以使用一种格式或另一种格式。只需将其设置为在所有机器上都相同即可。

希望这会有所帮助, 亚历克斯

【讨论】:

谢谢亚历克斯,我将运行一些测试来确定我不同平台的字节顺序.. 好吧,我的 mac 机器和 windows 平台上的字节顺序似乎完全相同,所以我怀疑字节顺序与它有什么关系。不过还是谢谢.. 丹也可能是对的,这就是问题所在。特别是 int 不必在通常的 4 个字节附近。不幸的是,我没有任何第一手经验。顺便提一句。阅读失败到底是什么意思?对于任何数据类型?错误的值或错误? 谢谢@Fritz -- 我还在调试代码,想知道到底发生了什么......当我弄清楚时会更新......【参考方案3】:

还有一个疯狂的猜测: 您忘记了以二进制读取模式打开文件,以及在 Windows 文件流上打开文件 将序列 13,10 转换为 10。

【讨论】:

我很抱歉,但我完全不明白你的意思。你能澄清一下吗? 我的意思是你在windows上打开文件流时使用std::ios::binary之类的东西吗? 感谢您的建议。我意识到在一些地方,我确实忘记了使用 std::ios::binary。我对此感到有点傻,但现在一切似乎都很好,并且序列化按预期工作:-)【参考方案4】:

您是否考虑过使用序列化库或格式,例如:

XDR(由 libc 支持)或 ASN1 s11n(一个 C++ 序列化库) Json,一种非常简单的文本格式,包含许多库,例如JsonCpp, Jansson, Jaula, ....) YAML,一种更强大的文本格式,包含许多库 甚至XML,通常用于序列化目的...

(对于标量的序列化,htonl 和配套例程应该会有所帮助)

【讨论】:

感谢您的建议——我没有听说过这些想法,除了 XML...感谢您打开我的眼睛。我仍然会尝试我首先做的方式,因为在我看来它应该可以工作......当我修复时会更新:-)

以上是关于关于windows下C++程序移植到linux下的一些头文件对应问题的主要内容,如果未能解决你的问题,请参考以下文章

java程序,在linux下能否调用windows下的mysql。。。。。。急急急急

将数据序列化代码从 C++ linux/mac 移植到 C++ windows

Linux下的路径在windows下怎么表示? 比如一个程序在linux下设置为/etc/users,那么在windows下怎么设置?

有在linux平台下运行的程序,想移植到windows平台下,但有些头文件不知道该怎么办?

windows与linux 头文件对照

Windows程序移植到linux下 出现很多头文件里面定义的变量在linux中找不到想对应的头文件?求救~~~