Как использовать API сокетов C в C++ в z/OS
У меня проблемы с настройкой API сокетов C для правильной работы в 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
который инкапсулирует в основном весь файл. Не уверен, если это имеет значение.
9 ответов
Держите копию руководств IBM под рукой:
- Руководство по программированию на z/OS V1R11.0 XL C/C++
- Справочник по библиотеке выполнения z/OS V1R11.0 XL C/C++
Публикации IBM, как правило, очень хороши, но вам нужно привыкнуть к их формату, а также знать, где искать ответ. Довольно часто вы обнаружите, что функция, которую вы хотите использовать, защищена "макросом проверки возможностей".
Вам следует попросить вашего дружественного системного программиста установить справочную библиотеку XL C / C++: справочные страницы в вашей системе. Затем вы можете сделать что-то вроде "man connect", чтобы открыть страницу man для API сокета connect (). Когда я это делаю, вот что я вижу:
ФОРМАТ
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);
У меня не было проблем с использованием API сокетов BSD в C++, в GNU/Linux. Вот пример программы, которую я использовал:
#include <sys/socket.h>
int
main()
{
return AF_INET;
}
Поэтому я полагаю, что z/OS, вероятно, является здесь усложняющим фактором, поскольку я никогда раньше не использовал z/OS, тем более запрограммирован в нем, я не могу сказать этого окончательно.:-П
См. Раздел Использование сокетов z/OS UNIX System Services в Руководстве по программированию z/OS XL C/C++. Убедитесь, что вы включаете необходимые заголовочные файлы и используете соответствующие #defines.
Ссылка на документ с годами менялась, но вы сможете достаточно легко получить к ней доступ, найдя текущее местоположение раздела Support & Downloads на ibm.com и выполнив поиск по названию документации.
Так что постарайтесь
#define _OE_SOCKETS
прежде чем включить sys/socket.h
_OE_SOCKETS, по-видимому, просто включает / отключает определение символов, связанных с сокетом. В некоторых библиотеках не редкость иметь для этого кучу макросов, чтобы гарантировать, что вы не компилируете / связываете ненужные части. Макрос не является стандартным в других реализациях сокетов, он кажется чем-то специфичным для z/OS.
Посмотрите на эту страницу:
Компиляция и компоновка программы z/VM C Sockets
Возможно, вы захотите взглянуть на cpp-sockets, оболочку C++ для системных вызовов сокетов. Работает со многими операционными системами (Win32, POSIX, Linux, *BSD). Я не думаю, что это будет работать с z/OS, но вы можете взглянуть на включаемые файлы, которые он использует, и у вас будет много примеров проверенного кода, который хорошо работает на других ОС.
@Jax: The 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, который у меня есть.
Также уценка поставить эти странные _ как мои подчеркивания.
Вы должны просто иметь возможность написать абстракционный класс вокруг сокетов 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
Для получения дополнительной информации см. Параметры C89 в Руководстве пользователя z/OS XLC/C++.