about porting

本文针对Linux与Windows平台的差异,详细介绍了在socket编程、文件操作、时间处理等方面的跨平台编程技巧,提供了具体的代码示例及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.diybl.com/course/3_program/c/c_js/20100710/426527.html

http://www.cppblog.com/lyricc/archive/2012/01/12/164071.aspx

搞了几个跨Linux与Windows的项目,碰到很多问题,记下来,以供查考。另外,因为水平的原因,肯定错误在所难免,请读者一定指正。

  如无其它说明,本文所指Linux均表示2.6内核Linux,GCC编译器,Windows均表示Windows XP系统,Visual Studio 2005 sp1编译环境。

  下面大概分几个方面进行罗列:

socket

  Linux要包含

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
等头文件,而windows下则是包含 #include <winsock.h> 

  Linux中socket为整形,Windows中为一个SOCKET。

  Linux中关闭socket为close,Windows中为closesocket。

  Linux中有变量socklen_t,Windows中直接为int。

  因为linux中的socket与普通的fd一样,所以可以在TCP的socket中,发送与接收数据时,直接使用read和write。而windows只能使用recv和send。

  设置socet选项,比如设置socket为非阻塞的。Linux下为

flag = fcntl (fd, F_GETFL); 
fcntl (fd, F_SETFL, flag | O_NONBLOCK); 
,Windows下为 flag = 1; 
ioctlsocket (fd, FIONBIO, (unsigned long *) &flag); 

  当非阻塞socket的TCP连接正在进行时,Linux的错误号为EINPROGRESS,Windows的错误号为WSAEWOULDBLOCK。

file

  Linux下面,文件换行是"\n",而windows下面是"\r\n"。

  Linux下面,目录分隔符是"/",而windows下面是"\"。

  Linux与Windows下面,均可以使用stat调用来查询文件信息。但是,Linux只支持2G大小,而Windows只支持4G大小。为了支持更大的文件查询,可以在Linux环境下加_FILE_OFFSET_BITS=64定义,在Windows下面使用_stat64调用,入参为 struct __stat64。

  Linux中可根据stat的st_mode判断文件类型,有S_ISREG、S_ISDIR等宏。Windows中没有,需要自己定义相应的宏,如

#define S_ISREG(m) (((m) & 0170000) == (0100000)) 
#define S_ISDIR(m) (((m) & 0170000) == (0040000)) 

  Linux中删除文件是unlink,Windows中为DeleteFile。

time

  Linux中,time_t结构是32位的无符号整形。而windows中,time_t结构是64位的整形。如果要在windows始time_t为32位无符号整形,可以加宏定义,_USE_32BIT_TIME_T。

  Linux中,sleep的单位为秒。Windows中,Sleep的单位为毫秒。即,Linux下sleep (1),在Windows环境下则需要Sleep (1000)。

  Windows中的timecmp宏,不支持大于等于或者小于等于。

  Windows中没有struct timeval结构的加减宏可以使用,需要手动定义:

#define MICROSECONDS (1000 * 1000) 

#define timeradd(t1, t2, t3) do { \ 
(t3)->tv_sec = (t1)->tv_sec + (t2)->tv_sec; \ 
(t3)->tv_usec = (t1)->tv_usec + (t2)->tv_usec % MICROSECONDS; \ 
if ((t1)->tv_usec + (t2)->tv_usec > MICROSECONDS) (t3)->tv_sec ++; \ 
} while (0) 

#define timersub(t1, t2, t3) do { \ 
(t3)->tv_sec = (t1)->tv_sec - (t2)->tv_sec; \ 
(t3)->tv_usec = (t1)->tv_usec - (t2)->tv_usec; \ 
if ((t1)->tv_usec - (t2)->tv_usec < 0) (t3)->tv_usec --, (t3)->tv_usec += MICROSECONDS; \ 
} while (0) 

process

  Linux下可以直接使用system来调用外部程序。Windows最好使用WinExec,因为WinExec可以支持是打开还是隐藏程序窗口。用WinExec的第二个入参指明,如SW_SHOW/SW_HIDE。

杂项

  Linux为srandom和random函数,Windows为srand和rand函数。

  Linux为snprintf,Windows为_snprintf。

  同理,Linux中的strcasecmp,Windows为_stricmp。

错误处理

  Linux下面,通常使用全局变量errno来表示函数执行的错误号。Windows下要使用GetLastError ()调用来取得。

Linux环境下仅有的

  这些函数或者宏,Windows中完全没有,需要用户手动实现。

  atoll

long long 
atoll (const char *p) 

int minus = 0; 
long long value = 0; 
if (*p == '-') 

minus ++; 
p ++; 

while (*p >= '0' && *p <= '9') 

value *= 10; 
value += *p - '0'; 
p ++; 

return minus ? 0 - value : value; 

gettimeofday

#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) 
#define EPOCHFILETIME 11644473600000000Ui64 
#else 
#define EPOCHFILETIME 11644473600000000ULL 
#endif 

struct timezone 

int tz_minuteswest; 
int tz_dsttime; 
}; 

int 
gettimeofday (struct timeval *tv, struct timezone *tz) 

FILETIME ft; 
LARGE_INTEGER li; 
__int64 t; 
static int tzflag; 

if (tv) 

GetSystemTimeAsFileTime (&ft); 
li.LowPart = ft.dwLowDateTime; 
li.HighPart = ft.dwHighDateTime; 
t = li.QuadPart; /* In 100-nanosecond intervals */ 
t -= EPOCHFILETIME; /* Offset to the Epoch time */ 
t /= 10; /* In microseconds */ 
tv->tv_sec = (long) (t / 1000000); 
tv->tv_usec = (long) (t % 1000000); 


if (tz) 

if (!tzflag) 

_tzset (); 
tzflag++; 

tz->tz_minuteswest = _timezone / 60; 
tz->tz_dsttime = _daylight; 


return 0; 
}

### ArduPilot IOFirmware Documentation and Resources ArduPilot IOFirmware refers to the firmware designed specifically for input/output (IO) peripherals that work alongside the main autopilot system. This allows offloading of certain tasks such as sensor management, actuator control, or communication handling onto separate hardware units[^1]. These peripheral devices communicate with the central flight controller via protocols like CAN bus. For detailed information about configuring and developing these peripherals: - **Official Documentation**: Comprehensive guides are available at [Ardupilot Developer Site](https://ardupilot.org/dev/docs/ap-peripheral-landing-page.html). Here one can find setup instructions, API references, and examples specific to various types of sensors and actuators supported by AP_Periph. - **Source Code Repository**: For those interested in exploring or contributing to the development process, all source files reside within GitHub repositories under the organization account `ardupilot`. Specifically looking into submodules related to `AP_HAL` (Hardware Abstraction Layer), which plays a crucial role in interfacing different microcontroller platforms used across multiple projects including IO firmwares. Additionally, community forums provide valuable insights through discussions between developers who share experiences troubleshooting common issues encountered during implementation phases. Users often post questions regarding integration challenges faced while working on custom setups involving third-party components not directly covered in official materials. #### Example Configuration Snippet To illustrate how an external module might be configured using parameters defined within the codebase: ```cpp // Define parameter groupings for this particular device type PARAM_GROUP_DEFINE(AP_PERIPH); // Register individual settings accessible over MAVLink/GCS interfaces static const struct { uint8_t id; char name[PARAM_NAME_LENGTH]; } param_list[] PROGMEM = { { PERIPH_PARAM_ID_ENABLE, "ENABLE" }, }; ``` --related problems-- 1. How does one go about setting up a new sensor connected via CAN Bus? 2. What steps should be taken when porting existing drivers to support newer MCU architectures? 3. Can you explain more about integrating non-standard peripherals without modifying core libraries? 4. Are there any best practices recommended for testing newly developed modules before deployment?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值