我在让 C 套接字 API 在 C++ 中正常工作时遇到问题 z/OS.

虽然我包括 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

它基本上封装了整个文件。不确定这是否重要。

有帮助吗?

解决方案

随身携带一份 IBM 手册:

IBM 出版物通常都非常好,但您需要习惯它们的格式,并知道在哪里寻找答案。您经常会发现您想要使用的功能受到“功能测试宏”的保护

您应该请您友好的系统程序员安装 XL C/C++ 运行时库参考:手册页 在您的系统上。然后,您可以执行“man connect”之类的操作来调出套接字 connect() API 的手册页。当我这样做时,我看到的是:

格式

X/打开

#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);

其他提示

我在 GNU/Linux 中使用 C++ 中的 BSD 套接字 API 时没有遇到任何问题。这是我使用的示例程序:

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

所以我的看法是,z/OS 可能是这里的复杂因素,但是,因为我以前从未使用过 z/OS,更不用说在其中编程了,所以我不能明确地说这一点。:-P

请参阅 使用 z/OS UNIX 系统服务套接字 z/OS XL C/C++ 编程指南中的部分。确保包含必要的头文件并使用适当的#defines。

该文档的链接多年来已发生变化,但您应该能够通过查找该文档的当前位置轻松访问它 支持和下载部分ibm.com 并按标题搜索文档。

所以尝试一下

#define _OE_SOCKETS

在包含 sys/socket.h 之前

_OE_SOCKETS 似乎只是为了启用/禁用套接字相关符号的定义。在某些库中,使用一堆宏来执行此操作的情况并不罕见,以确保您不会编译/链接不需要的部分。该宏在其他套接字实现中并不是标准的,它似乎是 z/OS 特有的。

看看这个页面:
编译和链接 z/VM C 套接字程序

您可能想看看 cpp 套接字, ,套接字系统调用的 C++ 包装器。它适用于许多操作系统(Win32、POSIX、Linux、*BSD)。我认为它不适用于 z/OS,但您可以查看它使用的包含文件,并且您将获得许多在其他操作系统上运行良好的经过测试的代码示例。

@贾克斯:这 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代码中调整了这些调用。

另外markdown把这些奇怪的_作为我的下划线。

您应该能够围绕 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;
}

答案是使用以下 c89 标志:

 -D_OE_SOCKETS

示例如下;

 bash-2.03$ c89 -D_OE_SOCKETS [filename].c

有关更多信息,请查找 z/OS XLC/C++ 用户指南中的 C89 选项。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top