Мне стало любопытно, когда я попытался создать библиотеку сокетов общего назначения .so
.
У меня есть структура, определенная платформой, и функция, которая выглядит так:
## == sock.c
#ifdef __unix__
typedef int SOCKET;
#else
typedef struct UNISock {
_IN_ int af,
_IN_ int type,
_IN_ int protocol;
} SOCKET;
#endif
SOCKET socket_connect(char * hostname, int portnumber) {
#ifdef __unix__
SOCKET connfd = 0;
#else
SOCKET connfd = INVALID_SOCKET; // Windows struct eq of "0"
#endif
...
return connfd;
}
Который я затем пытаюсь импортировать и использовать из application.c
.
## == application.c
typedef void* (*_func)();
int main(int argc, char *argv[]) {
void* lib;
_func socket_connect;
_func init;
lib = dlopen("./socket.so", RTLD_NOW|RTLD_GLOBAL);
*(void**)(&socket_connect) = dlsym(lib, "socket_connect");
*(void**)(&init) = dlsym(lib, "init");
SOCKET connection = socket_connect("127.0.0.1", 1337);
}
Очевидно, я здесь не следую передовым методам языка Си, поскольку - ну, прежде всего, обычно вы помещаете эти структуры / определения в файл .h
, и все в порядке.
Но я начал задаваться вопросом, смогу ли я создать этот struct
на fly, и кое-как настроить его в application.c
без файла заголовка, который был связан во время компиляции.
Либо сделав что-то похожее на extern typedef int SOCKET;
и загрузив его с помощью dlsym()
.
(extern
, очевидно, потерпит неудачу с multiple storage classes in declaration specifiers
, но это пример идеи, которую я пытаюсь реализовать)
Или имея функцию init()
в моей библиотеке сокетов, которая возвращала sizeof(SOCKET)
, чтобы я мог использовать malloc()
в application.c
для создания заполнителя памяти для любых байтов, которые SOCKET
потребуются при распределении памяти, и делать это вручную.
Поскольку я не знаю никого, кто исследовал бы эти вещи на C - и поиск тем в Интернете, похоже, не дает никакой информации по теме, кроме ссылки на разные категории вирусов в Википедии.
Или некоторые threads полностью избегает возвращаемых значений из библиотечных функций.
Поэтому я задаю расплывчатый вопрос в надежде, что кто-то знает, как:
- Сохраните / предоставьте символ
struct SOCKET
компоновщику / компилятору, добавив его в дерево символов, и каким-то образом используйтеdlsym()
или подобное для его настройки. - Получите
SOCKET
информацию отsocket.so
доapplication.c
, чтобыapplication.c
мог сохранить возвращаемое значениеsocket_connect
без необходимости загромождать основной кодtypedef
дляSOCKET
- поскольку это уже было сделано один раз вsocket.c
. И безsocket.h
- потому что цель состоит в том, чтобы обойти необходимость в файле заголовка. - Любые альтернативные способы обработки возвращаемых значений из библиотечных функций без предварительного определения потенциально сотен
struct
/ typedef информации в основном коде приложения.
Я понимаю, что это склоняется к ООП и, опять же, это не традиционный C. И я прошу прощения, если этот вопрос выходит за рамки темы или оскорбляет любого программиста.