我遇到问题让C套接字API在z/OS
上的C ++中正常工作。
虽然我包含sys/socket.h
,但我仍然遇到编译时错误,告诉我AF_INET
未定义。
我是否遗漏了一些明显的东西,或者这与z/OS
上的问题相关的事实更加复杂了?
更新:经过进一步调查,我发现我正在点击#ifdef
。显然z/OS
不开心,除非我定义我正在使用的“类型”套接字:
#define _OE_SOCKETS
现在,我个人不知道这个_OE_SOCKETS
实际上是什么,所以如果任何z/OS
套接字程序员在那里(你们三个人),或许你可以给我一个如何概述一切都有效吗?
测试应用
#include <sys/socket.h>
int main()
{
return AF_INET;
}
编译/链接输出:
cxx -Wc,xplink -Wl,xplink -o inet_test inet.C
"./inet.C", line 5.16: CCN5274 (S) The name lookup for "AF_INET" did not find a declaration.
CCN0797(I) Compilation failed for file ./inet.C. Object file not created.
对sys / sockets.h的检查确实包含了我需要的定义,据我所知,它没有被任何#ifdef语句阻止。
但我注意到它包含以下内容:
#ifdef __cplusplus
extern "C" {
#endif
基本上封装了整个文件。不确定是否重要。
答案 0 :(得分:78)
保留IBM手册的副本:
IBM出版物通常非常好,但您需要习惯他们的格式,以及知道在哪里寻找答案。您会经常发现您想要使用的功能受到“功能测试宏”的保护
您应该让友好的系统程序员在您的系统上安装XL C/C++ Run-Time Library Reference: Man Pages 。然后,您可以执行“man connect”之类的操作来拉出socket connect()API的手册页。当我这样做时,这就是我所看到的:
FORMAT
的X / Open
#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>
int connect(int socket, const struct sockaddr *address, socklen_t address_len);
伯克利套接字
#define _OE_SOCKETS
#include <sys/types.h>
#include <sys/socket.h>
int connect(int socket, struct sockaddr *address, int address_len);
答案 1 :(得分:36)
我在GNU / Linux中使用C ++中的BSD套接字API没有遇到任何麻烦。这是我使用的示例程序:
#include <sys/socket.h>
int
main()
{
return AF_INET;
}
所以我对此的看法是,z / OS可能是这里的复杂因素,但是,因为我之前从未使用过z / OS,更不用说编程了,我不能肯定地说这个。 :-P
答案 2 :(得分:31)
请参阅“z / OS XL C / C ++编程指南”中的使用z / OS UNIX系统服务套接字部分。确保包含必要的头文件并使用适当的#defines。
多年来,该文档的链接已发生变化,但您应该能够轻松地找到Support & Downloads section上ibm.com的当前位置并按标题搜索文档。
答案 3 :(得分:25)
所以试试
#define _OE_SOCKETS
包含sys / socket.h之前
答案 4 :(得分:25)
_OE_SOCKETS似乎只是启用/禁用与套接字相关的符号的定义。在某些库中,有一堆宏来执行此操作并不罕见,以确保您不编译/链接不需要的部分。宏在其他套接字实现中不是标准的,它似乎是z / OS特有的。
答案 5 :(得分:19)
您可能需要查看cpp-sockets,它是套接字系统调用的C ++包装器。它适用于许多操作系统(Win32,POSIX,Linux,* BSD)。我认为它不适用于z / OS,但你可以看看它使用的包含文件,你会有许多经过测试的代码示例,这些代码在其他操作系统上运行良好。
答案 6 :(得分:17)
@Jax:extern "C"
这件事非常重要。如果头文件没有头文件,那么(除非它是一个只有C ++的头文件),你必须用你的#include
括起来:
extern "C" {
#include <sys/socket.h>
// include other similarly non-compliant header files
}
基本上,只要C ++程序想要链接到基于C的设施,extern "C"
就至关重要。实际上,它意味着外部引用中使用的名称不会像正常的C ++名称那样被破坏。 Reference.
答案 7 :(得分:13)
免责声明:我不是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;
};
然后有方法在套接字上打开,关闭和发送数据包。
例如,公开呼叫可能如下所示:
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;
}
答案 8 :(得分:13)
答案是使用下面的c89标志:
-D_OE_SOCKETS
示例如下;
bash-2.03$ c89 -D_OE_SOCKETS [filename].c
有关更多信息,请参阅z / OS XLC / C ++用户指南中的C89选项。