我在使C套接字API在z/OS的C++中正常工作时遇到问题。
尽管我包括了sys/socket.h,但是仍然出现编译时错误,告诉我AF_INET没有定义。
我是否遗漏了一些明显的东西,或者与z/OS上的问题使我的问题更加复杂这一事实有关?
更新:经过进一步调查,我发现我遇到了一个#ifdef。显然,除非我定义与我一起使用的套接字的"类型",否则z/OS是不满意的:
现在,我个人不知道此_OE_SOCKETS的实际用途,因此,如果有任何z/OS套接字程序员在那里(你们所有人中的3个人),也许您可??以给我一个简要介绍一下这一切的原理吗?
测试应用
1 2 3 4 5 6
| #include <sys/socket.h>
int main()
{
return AF_INET;
} |
编译/链接输出:
1 2 3 4
| 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语句阻止。
但是,我注意到它包含以下内容:
1 2 3
| #ifdef __cplusplus
extern"C" {
#endif |
基本上封装了整个文件?不确定是否重要。
随手保存一份IBM手册副本:
-
z / OS V1R11.0 XL C / C ++编程指南
-
z / OS V1R11.0 XL C / C ++运行时库参考
IBM出版物通常很好,但是您需要习惯它们的格式,以及知道在哪里寻找答案。您会经常发现要使用的功能受"功能测试宏"保护
您应该请友好的系统程序员安装XL C / C ++运行时库参考:手册页
在您的系统上。然后,您可以执行诸如" man connect"之类的操作来拉出套接字connect()API的手册页。当我这样做时,这就是我看到的:
格式
X /开
1 2 3 4
| #define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>
int connect(int socket, const struct sockaddr *address, socklen_t address_len); |
伯克利插座
1 2 3 4 5
| #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时,我没有遇到任何麻烦。这是我使用的示例程序:
1 2 3 4 5 6 7
| #include <sys/socket.h>
int
main()
{
return AF_INET;
} |
因此,我对此的看法是z / OS可能是这里的复杂因素,但是,因为我以前从未使用过z / OS,因此其中的编程要少得多,所以我不能确定地说。 :-P
请参阅《 z / OS XL C / C ++编程指南》中的"使用z / OS UNIX系统服务"套接字部分。确保包含必要的头文件并使用适当的#define。
多年来,指向该文档的链接已经发生了变化,但是您应该可以通过在ibm.com上找到"支持和下载"部分的当前位置并按标题搜索文档来轻松地找到它。
_OE_SOCKETS似乎只是为了启用/禁用套接字相关符号的定义。在某些库中,有很多宏可以做到这一点,以确保您无需编译/链接不需要的部分,这种情况并不少见。该宏在其他套接字实现中不是标准的,它似乎是z / OS特有的。
看一下这个页面:
编译和链接z / VM C套接字程序
所以尝试
在包含sys / socket.h之前
您可能想看看cpp-sockets,这是套接字系统调用的C ++包装器。它可用于许多操作系统(Win32,POSIX,Linux,* BSD)。我认为它不适用于z / OS,但是您可以看一下它使用的包含文件,并且将有许多经过测试的代码示例,这些示例在其他OS上也能很好地工作。
@Jax:extern"C"很重要。如果头文件没有,那么(除非它是仅C ++的头文件),您必须将#include括起来:
1 2 3 4
| extern"C" {
#include <sys/socket.h>
// include other similarly non-compliant header files
} |
基本上,任何时候只要C ++程序想要链接到基于C的工具,extern"C"都是至关重要的。实际上,这意味着外部引用中使用的名称不会像普通的C ++名称那样被修饰。参考。
免责声明:我不是C ++程序员,但是我非常了解C。一世
从我拥有的一些C代码适应了这些调用。
降价促销也把这些奇怪的东西作为我的下划线。
您应该只能够在C套接字周围编写一个类似以下内容的抽象类:
1 2 3 4 5 6 7 8
| 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;
}; |
然后,有一些方法可用于通过套接字打开,关闭和发送数据包。
例如,公开通话可能看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| int my_socket_connect()
{
int return_code = 0;
if ( this->socket_type != CLIENT_SOCK ) {
cout <<"This is a not a client socket!\
";
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\
", strerror(errno);
return return_code;
}
return return_code;
} |
答案是使用下面的c89标志:
示例如下;
1
| bash-2.03$ c89 -D_OE_SOCKETS [filename].c |
有关更多信息,请在《 z / OS XLC / C ++用户指南》中查找" C89选项"。