欢迎大家来到IT世界,在知识的湖畔探索吧!
在程序开发的具体编码中,需要注意跨平台,下面整理了跨平台开发的部分注意事项。
1、 注意Linux和Windows操作系统API差异
2、 注意数据类型差异
linux数据类型 windows数据类型
INT8 int8_t
UINT8 uint8_t
INT16 int16_t
UINT16 uint16_t
INT32 int32_t
UINT32 uint32_t
INT64 int64_t
UINT64 uint64_t
欢迎大家来到IT世界,在知识的湖畔探索吧!
对于跨平台程序,尽量不要使用VC独有的数据类型,象__int16, __int32 和__int64 等等,你无法保证其它的编译器能否支持它们。
如果真的需要,则可以使用以下方式处理:
欢迎大家来到IT世界,在知识的湖畔探索吧!#include<stdio.h>
#if defined _WIN32 //此宏在windows下的32位程序和64位程序都有定义
#include <Windows.h> //此头文件中包含有类型定义
#else ifdef __linux__ //Linux系统宏
typedef short __int16
typedef int __int32
typedef long long __int64
typedef unsigned long DOWRD
typedef int BOOL
typedef unsigned char BYTE
typedef unsigned short WORD
typedef int INT
typedef unsigned int UINT
#endif
3、 #pragma once 避免同一个文件被包含多次,可移植性不好,linux下可能就会报错,
尽量使用以下方式防止重复包含头文件:
#ifndef XXXXXXXXX_XXXXX_H
#define XXXXXXXXX_XXXXX_H
//中间为函数、变量声明
#endif // XXXXXXXXX_XXXXX_H
4、 标准头文件路径
欢迎大家来到IT世界,在知识的湖畔探索吧!#if defined _WIN32
#include <io.h>//windows
#else ifdef __linux__ //Linux系统宏
#include <sys/io.h>
#endif
5、 跨平台动态库头文件定义
#if defined (_WIN32)
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif // MY_EXPORTS
#else ifdef (__linux__)
#define MY_API __attribute__((visibility(“default”)))
#else
#define MY_API
#endif //(_WIN32)
6、 库加载方式差异
在windows中可以用 #pragma comment(lib, …),例如:
#ifdef _WIN32
#pragma comment(lib, "osip2.lib")
#pragma comment(lib, "osipparser2.lib")
#pragma comment(lib, "eXosip.lib")
#pragma comment(lib, "InterProtocol.lib")
#pragma comment(lib, "tinyxml.lib")
#endif
在linux中不能使用#pragma comment(lib, …)方式加载库,需要直接编译的时候链接动态库和静态库;例如:
gcc -gbserver data.c -leXosip2 -ljrtp -ljthread -losip2 -losipparser2 -ltinyxml
7、 路径分割符差异:
在windows下同时支持“/”和“\”,而在Linux下只支持”/”
8、字符串处理差异:
#include<stdio.h>
_stricmp strcasecmp //比较两个字符串大小,但是不区分大小写。
strtok_s strtok_r //根据指定分隔符分隔字符串
sprintf_s snprintf //数据格式化输出到字符串
vsprintf_s vsnprintf //sprintf_s安全版本
srcpy_s strncpy //字符串拷贝
strcat_s strncat //字符串拼接
9、sokcet差异
socket的几个主要函数都一样,socket、bind、listen、connect、accept、select、send以及recv,
细微差异在与win32使用套接字运行TCP/IP协议需要初始化上下文环境
1、对于socket定义,Win32使用SOCKET,Linux使用int,
2、关闭套接字时,Win32使用closesocket,Linux使用close。
10、 进程差异
Windows平台使用CreateProcess来创建进程,子进程返回句柄喝ID给父进程,
在Linux平台中使用fork和execv来创建进程,子进程返回ID给父进程
CreateProcess fork/execv //创建进程
TerminateProcess kill //终止指定进程及其所有的线程
ExitProcess exit //结束调用的进程及其所有线程
GetCommandLine argv //获取进程的命令行参数
GetCurrentProcessId getpid //获取当前进程ID
GetExitCodeProcess waitpid //获取进程退出码
11、 线程差异
_beginthreadex pthread_create //创建线程
_endthreadex ptread_exit //终止线程(可以不在线程函数中显示调用,因为线程函数返回后,会自动调用)
TerminateThread pthread_cancel //在线程外终止一个线程,用于强制终止线程。
GetCurrentThreadId phread_self //获取当前线程ID
﹡注意:
Linux下需要按照如下进行线程创建(即在创建线程时需指定其实独立的),否则会有内存泄露
int hThread = 0;
pthread_attr_t attr;
pthread_t pid;
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
hThread = pthread_create(&pid, &attr, _threadCreateSafeChannel, NULL);
pthread_attr_destroy (&attr);
12、 线程锁
CreateMutex pthread_mutex_init //互斥锁初始化
CloseHandle pthread_mutex_destroy //互斥锁销毁
WaitForSingleObject pthread_mutex_lock //互斥锁上锁
ReleaseMutex pthread_mutex_unlock //互斥锁解锁
13、 事件锁差异
Windows下有事件锁Event,而在Linux下没有;自己可以实现
14、 毫秒级时间获取
windows下:GetTickCount()
linux下:gettimeofday()
15、 获取系统函数执行错误码
getlasterror()/WSAGetLastError();//windows
//linux环境下
未能成功执行的socket操作会返回-1, 如果包含了errno.h,就会设置errno变量(strerror(errno))
16、 Sleep函数
Linux下对应的睡眠函数为sleep和usleep,不同点在于,sleep函数对应的睡眠时间参数是以秒为单位,
usleep函数对应的睡眠时间参数是以微秒为单位的。而windows下的Sleep函数的参数是以毫秒为单位。
17、 函数返回值
在Windows VS下,编译void main()可以通过,但在Linux下面则不支持void类型的main函数,
必须要返回int值。
18、另外加一个注意事项,不区分windows和linux,在使用string对象转换成c字符串传递参数的危险,如果按照如下操作,就会将string对象中内容修改掉:
int fun1(char* pParam)
{
pParam[0] = ‘1’;
}
int fun2(const char* pParam)
{
fun1((char*) pParam);
}
int main(void)
{
string str1 = “abcdefghikmlnopqisg”;
fun2(str1.c_str())
printf(“str1 = %s”, str1.c_str());
}
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/32154.html