如何在z / OS上使用C ++中的C socket API
我一直有问题让C的套接字API在C ++中正常工作。 具体来说,虽然我包括sys/socket.h
,但仍然有编译时错误告诉我AF_INET
没有被定义。 我是否错过了一些显而易见的东西,或者这可能与我在z/OS
上进行这种编码的事实有关,而且我的问题更加复杂?
更新 :经过进一步的调查,我发现有一个#ifdef
我打。 显然z/OS
是不开心,除非我定义我使用的套接字“types”:
#define _OE_SOCKETS
现在,我个人不知道这个_OE_SOCKETS
实际上是什么,所以如果有任何z/OS
套接字程序员在那里(你们全部3个),也许你可以给我一个如何工作的概要?
当然,我可以发布testing应用程序。
#include <sys/socket.h> int main() { return AF_INET; }
编译/链接输出:
cxx -Wc,xplink -Wl,xplink -o inet_test inet.C
“./inet.C”,行5.16:CCN5274(S)“AF_INET”的名称查找没有find声明。
(I)编译文件./inet.C失败。 目标文件未创build。
sys / sockets.h的检查确实包括了我所需要的定义,就我所知,它并没有被任何#ifdef语句阻塞。
但是我注意到它包含以下内容:
#ifdef __cplusplus extern "C" { #endif
它基本上封装了整个文件。 不知道是否重要。
方便地保留IBM手册的副本:
- z / OS V1R11.0 XL C / C ++编程指南
- z / OS V1R11.0 XL C / C ++运行时库参考
IBM的出版物一般都非常好,但是您需要习惯他们的格式,以及知道在哪里寻找答案。 你会经常发现你想要使用的function是由“functiontestingmacros”来保护的,
你应该让你友好的系统程序员在你的系统上安装XL C / C ++运行库参考:手册页 。 然后你可以做一些事情,比如“man connect”来为套接字connect()API拉上手册页。 当我这样做的时候,这就是我所看到的:
格式
在X / Open
#define _XOPEN_SOURCE_EXTENDED 1 #include <sys/socket.h> int connect(int socket, const struct sockaddr *address, socklen_t address_len);
伯克利sockets
#define _OE_SOCKETS #include <sys/types.h> #include <sys/socket.h> int connect(int socket, struct sockaddr *address, int address_len);
我在GNU / Linux中使用C ++中的BSD套接字API没有任何问题。 以下是我使用的示例程序:
#include <sys/socket.h> int main() { return AF_INET; }
所以我认为z / OS在这里可能是一个复杂的因素,然而,因为我以前从来没有使用过z / OS,更不用说编程了,所以我不能说这是明确的。 😛
请参阅“z / OS XL C / C ++编程指南”中的使用z / OS UNIX系统服务套接字一节。 确保你包含必要的头文件并使用适当的#defines。
多年以来,文档链接已经发生了变化,但您应该可以通过查找ibm.com上“ 支持与下载”部分的当前位置并按标题search文档来轻松find它。
_OE_SOCKETS似乎只是为了启用/禁用套接字相关符号的定义。 在一些图书馆里有一堆macros来做这件事情,这是不常见的,以确保你不编译/链接不需要的部分。 这个macros在其他套接字实现中不是标准的,它似乎是z / OS特有的。
看看这个页面:
编译和链接z / VM C套接字程序
所以试试
#define _OE_SOCKETS
在包含sys / socket.h之前
你可能想看看cpp-sockets ,一个用于套接字系统调用的C ++封装器。 它适用于许多操作系统(Win32,POSIX,Linux,* BSD)。 我不认为它可以在z / OS上工作,但是你可以看看它使用的包含文件,你会有很多testing代码的例子,在其他操作系统上运行良好。
@Jax: extern "C"
事情非常重要。 如果一个头文件没有一个,那么(除非它是一个只有C ++的头文件),否则你必须用#include
括起来:
extern "C" { #include <sys/socket.h> // include other similarly non-compliant header files }
基本上,只要C ++程序想要链接到基于C的设备, extern "C"
就非常重要。 实际上,这意味着在外部引用中使用的名称不会像通常的C ++名字那样被破坏。 参考。
免责声明:我不是一个C ++程序员,但我知道C真的很好。 我从一些C代码中调用了这些调用。
另外减价把这些奇怪_作为我的下划线。
你应该能够用这样的方式来编写一个抽象类来围绕C套接字:
class my_sock { private int sock; private int socket_type; private socklen_t sock_len; private struct sockaddr_in server_addr; public char *server_ip; public unsigned short server_port; };
然后有方法来打开,closures和发送数据包的sockets。
例如,公开呼叫可能看起来像这样:
int my_socket_connect() { int return_code = 0; if ( this->socket_type != CLIENT_SOCK ) { cout << "This is a not a client socket!\n"; return -1; } return_code = connect( this->local_sock, (struct sockaddr *) &this->server_addr, sizeof(this->server_addr)); if( return_code < 0 ) { cout << "Connect() failure! %s\n", strerror(errno); return return_code; } return return_code; }
答案是使用下面的c89标志:
-D_OE_SOCKETS
示例如下。
bash-2.03$ c89 -D_OE_SOCKETS [filename].c
有关更多信息,请参见“z / OS XLC / C ++用户指南”中的“C89选项”。