Ik heb problemen om de C sockets API correct te laten werken in C++ op z/OS.
Hoewel ik sys/socket.h
gebruik, krijg ik nog steeds fouten tijdens het compileren die me vertellen dat AF_INET
niet is gedefinieerd.
Mis ik iets voor de hand liggends, of heeft dit te maken met het feit dat het gebruik van z/OS mijn problemen veel gecompliceerder maakt?
Ik ontdekte dat er een #ifdef
is die ik aanraak. Blijkbaar is z/OS niet tevreden, tenzij ik definieer met welk “type” sockets ik gebruik:
#define _OE_SOCKETS
Ik heb persoonlijk geen idee waar deze _OE_SOCKETS
eigenlijk voor is, dus als er z/OS sockets-programmeurs zijn (jullie alle drie), kun je me misschien een overzicht geven van hoe werkt dit allemaal?
App testen
#include <sys/socket.h>
int main()
{
return AF_INET;
}
Uitvoer compileren/linken:
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.
Een controle van sys/sockets.h bevat de definitie die ik nodig heb, en voor zover ik weet, wordt deze niet geblokkeerd door #ifdef
-statements.
Ik heb echter gemerkt dat het het volgende bevat:
#ifdef __cplusplus
extern "C" {
#endif
die in feite het hele bestand inkapselt? Ik weet niet zeker of het ertoe doet.
Antwoord 1, autoriteit 100%
Houd een kopie van de IBM-handleidingen bij de hand:
De IBM-publicaties zijn over het algemeen erg goed, maar je moet aan hun formaat wennen en weten waar je het antwoord moet zoeken. U zult vaak merken dat een functie die u wilt gebruiken, wordt bewaakt door een “functietestmacro”
Vraag je vriendelijke systeemprogrammeur om de te installeren XL C/C++ Runtime Bibliotheek Referentie: Man Pages
op uw systeem. Dan kun je dingen doen als “man connect” om de man-pagina voor de socket connect() API op te halen. Als ik dat doe, zie ik dit:
FORMAAT
X/Open
#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>
int connect(int socket, const struct sockaddr *address, socklen_t address_len);
Berkeley-contactdozen
#define _OE_SOCKETS
#include <sys/types.h>
#include <sys/socket.h>
int connect(int socket, struct sockaddr *address, int address_len);
Antwoord 2, autoriteit 46%
Ik heb geen problemen gehad met het gebruik van de BSD sockets API in C++, in GNU/Linux. Dit is het voorbeeldprogramma dat ik heb gebruikt:
#include <sys/socket.h>
int
main()
{
return AF_INET;
}
Dus mijn mening hierover is dat z/OS hier waarschijnlijk de complicerende factor is, maar omdat ik z/OS nog nooit eerder heb gebruikt, laat staan erin geprogrammeerd, kan ik dit niet definitief zeggen. 😛
Antwoord 3, autoriteit 40%
Zie het gedeelte Z/OS UNIX System Services-sockets gebruikenin de z/OS XL C/C++ Programming Guide. Zorg ervoor dat u de benodigde header-bestanden opneemt en de juiste #defines gebruikt.
De link naar het document is in de loop der jaren veranderd, maar u zou er gemakkelijk genoeg moeten kunnen komen door de huidige locatie van de Ondersteuning & Sectie Downloadsop ibm.comen zoeken in de documentatie op titel.
Antwoord 4, autoriteit 33%
Probeer het dus
#define _OE_SOCKETS
voordat u sys/socket.h opneemt
Antwoord 5, autoriteit 33%
De _OE_SOCKETS lijkt eenvoudig te zijn om de definitie van socket-gerelateerde symbolen in of uit te schakelen. Het is in sommige bibliotheken niet ongebruikelijk om een heleboel macro’s te hebben om dat te doen, om er zeker van te zijn dat je geen onderdelen compileert/linkt die niet nodig zijn. De macro is niet standaard in andere sockets-implementaties, het lijkt iets specifieks te zijn voor z/OS.
Bekijk deze pagina:
Het az/VM C Sockets-programma compileren en koppelen
Antwoord 6, autoriteit 25%
@Jax: Het extern "C"
ding is heel erg belangrijk. Als een headerbestand er geen heeft (tenzij het een headerbestand is dat alleen in C++ is), moet u uw #include
erbij voegen:
extern "C" {
#include <sys/socket.h>
// include other similarly non-compliant header files
}
In principe is de extern "C"
van vitaal belang wanneer een C++-programma een koppeling wil maken met op C gebaseerde faciliteiten. In praktische termen betekent dit dat de namen die in externe verwijzingen worden gebruikt, niet worden verminkt, zoals normale C++-namen zouden doen. Referentie.
Antwoord 7, autoriteit 25%
Misschien wil je eens kijken naar cpp-sockets, een C++-wrapper voor de sockets systeem oproepen. Het werkt met veel besturingssystemen (Win32, POSIX, Linux, *BSD). Ik denk niet dat het zal werken met z/OS, maar je kunt eens kijken naar de include-bestanden die het gebruikt en je zult veel voorbeelden hebben van geteste code die goed werkt op andere besturingssystemen.
Antwoord 8, autoriteit 20%
DISCLAIMER: ik ben geen C++ programmeur, maar ik ken C heel goed. l
heb deze oproepen aangepast met een C-code die ik heb.
Zet deze vreemde _ ook als mijn onderstrepingstekens.
Je zou gewoon een abstractieklasse rond de C-sockets moeten kunnen schrijven met zoiets als dit:
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;
};
Beschik dan over methoden voor het openen, sluiten en verzenden van pakketten door de socket.
Het open gesprek kan er bijvoorbeeld ongeveer zo uitzien:
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;
}
Antwoord 9, autoriteit 19%
Gebruik de volgende c89-vlag:
-D_OE_SOCKETS
Voorbeeld:
bash-2.03$ c89 -D_OE_SOCKETS [filename].c
Zoek voor meer informatie naar c89-opties in de z/OS XLC/C++ Gebruikershandleiding.