c++ - socket - gcc vc 違い




z/OS上のC++でCソケットAPIを使用する方法 (6)

z/OS 上のC ++でCソケットAPIを正しく機能させるのに問題があります。

sys/socket.hsys/socket.h ていますが、 AF_INET が定義されていないことを示すコンパイル時エラーが発生します。

明らかな何かが足りないのでしょうか、それとも z/OS 上にいることが私の問題をはるかに複雑にするという事実に関連していますか?

更新 日:さらなる調査の結果、私は私が打っている #ifdef があることを発見しました。 私が使用しているソケットの「タイプ」を定義しない限り、 z/OS は満足していないようです。

#define _OE_SOCKETS

さて、私は個人的にこの _OE_SOCKETS が実際に何のためにあるのか _OE_SOCKETS ないので、もし z/OS ソケットプログラマーがいなければ(あなた全員3人)、おそらくこれがどのように機能するのかの概要を教えてください。

テストアプリ

#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

これは基本的にファイル全体をカプセル化しています。 それが重要かどうかわからない。


@ジャックス: extern "C" ことがとても大事です。 ヘッダーファイルにそれがない場合は、(C ++専用のヘッダーファイルでない限り) #include を同封する必要があります。

extern "C" {
#include <sys/socket.h>
// include other similarly non-compliant header files
}

基本的に、C ++プログラムがCベースの機能にリンクしたい場合はいつでも、 extern "C" が不可欠です。 実際的には、通常のC ++の名前のように、外部参照で使用されている名前が破損しないことを意味します。 Reference.


C ++、GNU / LinuxでBSDソケットAPIを使用しても問題ありません。 これが私が使ったサンプルプログラムです:

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

私の考えでは、z / OSはおそらくここでは複雑な要素になりますが、z / OSを使ったことは一度もないので、あまりプログラムされていないので、これは絶対的には言えません。 :-P


_OE_SOCKETSは単にソケット関連のシンボルの定義を有効/無効にするためのものです。 一部のライブラリでは、不要な部分をコンパイル/リンクしていないことを確認するために、それを行うためのマクロをたくさん用意することは珍しくありません。 このマクロは、他のソケット実装では標準的ではありません。z/ OSに固有のもののようです。

このページを見てください。
z / VM Cソケット・プログラムのコンパイルとリンク


「z / OS XL C / C ++プログラミング・ガイド」の 『 z / OS UNIXシステム・サービス・ソケットの使用』 セクションを参照してください。 必要なヘッダファイルをインクルードし、適切な#definesを使用していることを確認してください。

この文書へのリンクは長年にわたって変更されてきましたが、 ibm.com Support&Downloadsセクションの 現在の場所を見つけて、その文書をタイトルで検索すれば、簡単にアクセスできるはずです。


ソケットシステムコールのC ++ラッパーである cpp-sockets 見てみるとよいでしょう。 多くのオペレーティングシステム(Win32、POSIX、Linux、* BSD)で動作します。 私はそれがz / OSでうまくいくとは思わないが、あなたがそれが使用するインクルードファイルを見ることができるそして他のOSでうまくいくテストされたコードの多くの例があるでしょう。


免責事項:私は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;
};

それから、ソケットを開いたり閉じたり、パケットを送信するためのメソッドがあります。

たとえば、open呼び出しは次のようになります。

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;
}




zos