【发布时间】:2010-10-30 08:15:07
【问题描述】:
我有一个linux下的应用程序,编译成功。 我想在 Windows 中运行相同的程序。
但是编译会产生以下与头文件相关的错误。
- 找不到 sys/select.h
- 找不到 termios.h
我该如何解决这个问题?
【问题讨论】:
我有一个linux下的应用程序,编译成功。 我想在 Windows 中运行相同的程序。
但是编译会产生以下与头文件相关的错误。
我该如何解决这个问题?
【问题讨论】:
Windows API 在结构和风格上与任何风格的 Unix 提供的系统调用和库例程的混合都非常不同。
Windows 使用与任何 *nix 系统完全不同的模型来执行终端 I/O。因此,确实没有直接等效于 termios.h 标头及其朋友。
您想在 MSDN 上阅读有关 Windows Communications Resources 的信息。
需要了解的更多内容包括:
BuildCommDCB()SetCommState()一般来说,你会发现你需要直接处理更多的 Windows API,因为stdio 在进行设备 I/O 时会增加混乱。
没有直接等效于 Unix select(2) 系统调用。
在 Windows 中,许多内核对象可以处于有信号或无信号状态,发出信号的行为可以用来释放一个调用 WaitForMultipleObjects() 的线程。当数据可用时,一些但不是全部HANDLE 对象会发出信号。具体来说,我知道来自 WinSock 的HANDLEs 具有该功能,但我不了解 Comm API。我知道HANDLEs 对打开的文件没有。
如果您需要在处理窗口消息的线程中等待事件,那么您可能应该改用MsgWaitForMultipleObjects(),因为它会在线程被阻塞时正确传递消息。
在 MSDN 文章 Using Synchronization 中了解 Windows 同步原语。
但是,Windows 中内置了几种异步 I/O,可以通过更改设计来取代对 select() 的需求。两者都需要大量使用不能与 C stdio 库结合使用的特性。
MSDN 有几篇关于 I/O 技术的文章以及大量示例:
CreateFile()(尤其是备注部分)请注意,有关 Windows 工作原理的大部分信息都分散在概述文章和 API 函数和结构参考材料的备注部分中。这会给人一种印象,即在初读时没有完全记录在案。
另一种方法是使用Cygwin 来做端口。它在 Windows API 上提供了大部分 POSIX 层。但是,您最终会得到一个依赖于 GPL 的 Cygwin DLL 的应用程序,除非您从他们那里购买商业使用许可证。使用 Cygwin 来获得一个适用于没有 Unix 经验的 Windows 用户的应用程序可能会很棘手,因为关于这两个系统的设置和使用方式的许多其他假设都不同。
Cygwin 做了大量繁重的工作来构建select() 的实现,它可以在Windows 上运行,因为它混合了不同的打开文件描述符。这项工作是described in the User's Guide。
请注意,只有在 Cygwin 环境中进行构建时,才会记录和支持针对 Cygwin 的构建。仅将 Cygwin 的 bin 放在 Windows PATH 上并从命令提示符处工作通常是不够的。你真的需要启动 Cygwin 的 bash 构建并从那里编译,这样所有东西都使用相同的 Cygwin 风格的挂载点和模拟的 Unix 文件结构。
将 Cygwin 头文件与第三方工具头文件混用是疯狂的必经之路。
编辑:我已经重新安排了一下,并添加了一些材料以响应 cmets。
【讨论】:
termiWin 是一个库,其目的是允许您在 Windows 系统上使用,与 Linux 中用于通过串行端口与设备通信的代码相同。这是可能的,因为 termios 的函数已被重写以兼容 Windows 的 COM 函数。
我使用在一些论坛中找到的代码创建了 2 个文件来绕过 windows.h 和 windows com 端口库:
“nowindows.h”
/* file nowindows.h v1.0 use at your own risk *
#ifndef DWORD
#define WINAPI
typedef unsigned long DWORD;
typedef short WCHAR;
typedef void * HANDLE;
#define MAX_PATH PATH_MAX
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int BOOL;
#include <sys/types.h>
#include <sys/stat.h>
#include "unistd.h"
#include <fcntl.h>
#define GENERIC_READ O_RDONLY //read only mode
#define GENERIC_WRITE O_WRONLY //write only mode
#define CREATE_ALWAYS O_CREAT //create new file
#define OPEN_EXISTING 0 //fake parameter's value
#define FILE_ATTRIBUTE_NORMAL 0644 // file attributes
#endif
和
“nowindowscomport.h”
/* file nowindowscomport.h v1.0 use at your own risk *//
typedef struct _DCB {
DWORD DCBlength;
DWORD BaudRate;
DWORD fBinary :1;
DWORD fParity :1;
DWORD fOutxCtsFlow :1;
DWORD fOutxDsrFlow :1;
DWORD fDtrControl :2;
DWORD fDsrSensitivity :1;
DWORD fTXContinueOnXoff :1;
DWORD fOutX :1;
DWORD fInX :1;
DWORD fErrorChar :1;
DWORD fNull :1;
DWORD fRtsControl :2;
DWORD fAbortOnError :1;
DWORD fDummy2 :17;
WORD wReserved;
WORD XonLim;
WORD XoffLim;
BYTE ByteSize;
BYTE Parity;
BYTE StopBits;
char XonChar;
char XoffChar;
char ErrorChar;
char EofChar;
char EvtChar;
WORD wReserved1;
} DCB, *LPDCB;
typedef struct _COMSTAT {
DWORD fCtsHold :1;
DWORD fDsrHold :1;
DWORD fRlsdHold :1;
DWORD fXoffHold :1;
DWORD fXoffSent :1;
DWORD fEof :1;
DWORD fTxim :1;
DWORD fReserved :25;
DWORD cbInQue;
DWORD cbOutQue;
} COMSTAT, *LPCOMSTAT;
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS, *LPCOMMTIMEOUTS;
#define ERROR_INVALID_HANDLE 6L
/* Purge functions for Comm Port */
#define PURGE_TXABORT 0x0001 /* Kill pending/current @@-377,11 +382,4 @@ */
#define PURGE_RXCLEAR 0x0008
#define PURGE_TXCLEAR 0x0004
#define PURGE_RXABORT 0x0002
// DTR Control Flow Values.
#define DTR_CONTROL_DISABLE 0x00
#define DTR_CONTROL_ENABLE 0x01
#define DTR_CONTROL_HANDSHAKE 0x02
#define RTS_CONTROL_DISABLE 0x00
#define NOPARITY 0
#define ONESTOPBIT 0
【讨论】: