2008-08-01 57 views
124

我一直在讓C套接字API在C++中正常工作。具體來說,儘管我包含sys/socket.h,但編譯時錯誤仍然告訴我AF_INET未定義。我是否錯過了某些明顯的東西,或者這可能與我在z/OS上執行此編碼的事實有關,而且我的問題要複雜得多?如何在z/OS上使用C++中的C套接字API


更新:經進一步調查,我發現有一個#ifdef是我打。顯然z/OS不開心,除非我確定我使用的是與「型」插口

#define _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」,線路5.16:CCN5274(S) 「AF_INET」的名稱查找沒有找到聲明。

CCN0797(I)文件./inet.C的編譯失敗。目標文件未創建。

sys/sockets.h的檢查確實包括我需要的定義,並且據我所知,它沒有被任何#ifdef語句阻塞。

我已經注意到,但它包含以下內容:

#ifdef __cplusplus 
    extern "C" { 
#endif 

基本上封裝整個文件。不知道它是否重要。

回答

69

保持IBM手冊的副本,方便:

IBM出版物一般都非常好,但你必須習慣他們的格式,以及因爲知道在哪裏尋找答案。您經常會發現想要使用的功能是由「功能測試宏」保護的

您應該讓系統程序員在您的系統上安裝XL C/C++ Run-Time Library Reference: Man Pages 。然後,您可以執行諸如「man connect」之類的操作來爲套接字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); 
32

我在GNU/Linux中使用C++中的BSD套接字API沒有問題。下面是我使用的示例程序:

#include <sys/socket.h> 

int 
main() 
{ 
    return AF_INET; 
} 

所以我拿到這個是z/OS的可能是這裏的複雜因素,但是,因爲我從來沒有使用z/OS上,更在它編程,我無法確切地說出這一點。 :-P

15

@Jax:extern "C"事情很重要,非常非常。如果一個頭文件沒有一個,然後(除非它是一個C++ - 只有頭文件),你會用它附上#include

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

基本上,隨時隨地其中一個C++程序要鏈接到基於C的設施,extern "C"是至關重要的。實際上,這意味着在外部引用中使用的名稱不會像通常的C++名稱那樣被破壞。 Reference.

11

免責聲明:我不是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; 
} 
+0

這與原始問題無關。 – 2009-09-18 11:25:41

17

你可能想看看到cpp-sockets,一個C++包裝的插座系統調用。它適用於許多操作系統(Win32,POSIX,Linux,* BSD)。我認爲它不適用於z/OS,但您可以查看它使用的包含文件,並且您會有許多經過測試的代碼示例,這些示例在其他操作系統上運行良好。

23

所以儘量

#define _OE_SOCKETS 

你包括前SYS/socket.h中

23

的_OE_SOCKETS似乎是簡單的啓用/禁用插座相關符號的定義。在一些圖書館中有一堆宏來做這件事並不少見,以確保你不編譯/鏈接不需要的部分。該宏在其他套接字實現中不是標準的,它似乎是z/OS專用的。

在本頁面看看:
Compiling and Linking a z/VM C Sockets Program

+2

z/OS與z/VM一樣與Windows一樣,所以我有點困惑你爲什麼發佈這個鏈接。 – paxdiablo 2009-02-26 09:14:30

29

使用的z/OS UNIX系統服務插座在z/OS XL C/C++編程指南部分。確保你包含必要的頭文件並使用適當的#defines。

多年來,文檔的鏈接已經發生了變化,但您應該能夠通過找到Support & Downloads section的當前位置ibm.com並按標題搜索文檔來輕鬆找到它。

11

答案是使用下面的C89標誌:

-D_OE_SOCKETS 

例子隨之而來;

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

有關更多信息,請參見z/OS XLC/C++用戶指南中的C89選項。