Cómo utilizar la API de socket C en C++ en z/OS
sockets mainframe (9)
@Jax: Lo
extern "C"
muy importante.
Si un archivo de encabezado no tiene uno, entonces (a menos que sea un archivo de encabezado solo C ++), deberá incluir su
#include
con él:
extern "C" {
#include <sys/socket.h>
// include other similarly non-compliant header files
}
Básicamente, en cualquier momento en que un programa C ++ quiera vincularse a instalaciones basadas en C, la
extern "C"
es vital.
En términos prácticos, significa que los nombres usados en referencias externas no serán mutilados, como lo harían los nombres normales de C ++.
Reference.
Tengo problemas para que la API de sockets de C funcione correctamente en C ++ en
z/OS
.
Aunque
sys/socket.h
, sigo recibiendo errores de tiempo de compilación que me dicen que
AF_INET
no está definido.
¿Me estoy perdiendo algo obvio o está relacionado con el hecho de que estar en
z/OS
hace que mis problemas sean mucho más complicados?
Actualización
: Tras una investigación más profunda, descubrí que hay un
#ifdef
que estoy golpeando.
Aparentemente,
z/OS
no está contento a menos que defina con qué "tipo" de sockets estoy usando:
#define _OE_SOCKETS
Ahora, personalmente no tengo idea de para qué es realmente este
_OE_SOCKETS
, así que si hay algún programador de
z/OS
sockets (los 3), ¿tal vez podrían darme un resumen de cómo funciona todo esto?
Aplicación de prueba
#include <sys/socket.h>
int main()
{
return AF_INET;
}
Salida de compilación / enlace:
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.
Una comprobación de sys / sockets.h incluye la definición que necesito y, por lo que puedo decir, no está bloqueada por ninguna declaración #ifdef.
Sin embargo, he notado que contiene lo siguiente:
#ifdef __cplusplus
extern "C" {
#endif
que encapsula básicamente todo el archivo. No estoy seguro si importa.
Así que intenta
#define _OE_SOCKETS
antes de incluir sys / socket.h
Consulte la sección Uso de zócalos de servicios del sistema z / OS UNIX en la Guía de programación de z / OS XL C / C ++. Asegúrese de incluir los archivos de encabezado necesarios y usar los #defines apropiados.
El enlace al documento ha cambiado a lo largo de los años, pero debería poder acceder a él fácilmente encontrando la ubicación actual de la sección de Soporte y descargas en ibm.com y buscando en la documentación por título.
DESCARGO DE RESPONSABILIDAD: No soy un programador de C ++, sin embargo, conozco C muy bien. Adapté estas llamadas de algún código C que tengo.
También Markdown puso estos _ extraños como mis guiones bajos.
Debería poder escribir una clase de abstracción alrededor de los sockets C con algo como esto:
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;
};
Luego tenga métodos para abrir, cerrar y enviar paquetes por el socket.
Por ejemplo, la convocatoria abierta podría verse así:
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;
}
El _OE_SOCKETS parece ser simplemente para habilitar / deshabilitar la definición de símbolos relacionados con sockets. No es raro en algunas bibliotecas tener un montón de macros para hacer eso, para asegurarse de que no está compilando / vinculando partes que no son necesarias. La macro no es estándar en otras implementaciones de sockets, parece ser algo específico de z / OS.
Echa un vistazo a esta página:
Compilación y vinculación del programa z / VM C Sockets
Es posible que desee echar un vistazo a cpp-sockets , un contenedor de C ++ para las llamadas al sistema de sockets. Funciona con muchos sistemas operativos (Win32, POSIX, Linux, * BSD). No creo que funcione con z / OS, pero puede echar un vistazo a los archivos de inclusión que usa y tendrá muchos ejemplos de código probado que funciona bien en otros sistemas operativos.
La respuesta es usar la bandera c89 que sigue:
-D_OE_SOCKETS
Sigue el ejemplo;
bash-2.03$ c89 -D_OE_SOCKETS [filename].c
Para obtener más información, busque Opciones C89 en la Guía del usuario de z / OS XLC / C ++.
No he tenido problemas para usar la API de sockets BSD en C ++, en GNU / Linux. Aquí está el programa de muestra que utilicé:
#include <sys/socket.h>
int
main()
{
return AF_INET;
}
Entonces, mi opinión sobre esto es que z / OS es probablemente el factor de complicación aquí, sin embargo, porque nunca he usado z / OS antes, y mucho menos programado en él, no puedo decirlo definitivamente. :-PAGS
Tenga a mano una copia de los manuales de IBM:
- Guía de programación de z / OS V1R11.0 XL C / C ++
- Referencia de la biblioteca de tiempo de ejecución de z / OS V1R11.0 XL C / C ++
Las publicaciones de IBM son generalmente muy buenas, pero debe acostumbrarse a su formato, así como saber dónde buscar una respuesta. Encontrará con bastante frecuencia que una característica que desea utilizar está protegida por una "macro de prueba de características"
Debería pedirle a su amigable programador del sistema que instale la Referencia de la Biblioteca de Tiempo de Ejecución XL C / C ++: Páginas Man en su sistema. Luego, puede hacer cosas como "man connect" para abrir la página man de la API socket connect (). Cuando hago eso, esto es lo que veo:
FORMATO
X / abierto
#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>
int connect(int socket, const struct sockaddr *address, socklen_t address_len);
Enchufes Berkeley
#define _OE_SOCKETS
#include <sys/types.h>
#include <sys/socket.h>
int connect(int socket, struct sockaddr *address, int address_len);