关于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 statunsigned 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】:像这样的二进制序列化应该可以在这些平台上正常工作。您确实必须尊重字节顺序,但这是微不足道的。我认为这三个平台在这方面没有任何冲突。
不过,你真的不能使用松散的类型规范。 int
、float
、size_t
大小都可以跨平台变化。
对于整数类型,请使用在 cstdint 标头中找到的严格大小的类型。 uint32_t
、int32_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下怎么设置?