當我試圖創建一個通用套接字庫.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);
}
很顯然,我不是在這裏之後因爲C語言的最佳實踐 - 那麼首先,通常你把這些結構/定義在.h
文件,一切都很好。
但我開始懷疑我是否能產生這種struct
上的蒼蠅,以及一些如何設置它在application.c
沒有這是在編譯過程中鏈接的頭文件。
要麼執行類似於extern typedef int SOCKET;
的操作,要麼使用dlsym()
加載它。
(extern
將失敗,multiple storage classes in declaration specifiers
很明顯,但它的想法,我想實現的一個例子)
或在返回的sizeof(SOCKET)
,這樣我可以用malloc()
我的套接字庫具有init()
功能在application.c
爲內存分配需要的任何字節SOCKET
創建一個內存佔位符並手動執行。
因爲我不知道這是探索用C這些事情的人 - 和在線搜索線程似乎給除了鏈接我在維基百科不同的病毒種類的話題沒有任何信息。
或者一些threads避免完全從庫函數返回值。
所以我問一個模糊的問題,希望有人知道如何:
- 保持/將其添加到符號樹揭露
struct SOCKET
符號鏈接器/編譯器,以及一些如何使用dlsym()
或類似的設置。 - 獲取從
socket.so
的SOCKET
信息application.c
使application.c
可以存儲socket_connect
返回值,而不必與typedef
的雜亂下跌爲主代碼SOCKET
- 因爲這已經在socket.c
做一次。沒有socket.h
- 因爲我們的目標是解決對頭文件的需求。 - 任何替代的方式來處理從庫函數返回值而不定義預潛在數百在主應用程序代碼
struct
/typedef的信息。
我知道這是傾向於面向對象,並且它不是傳統的C.它既醜陋又不是任何人都會理智的,因爲C是一個人。我很抱歉,如果這個問題是邊界線題外話或冒犯每一位程序員。
我不相信你可以從DLL進口結構,後來編譯它不知道結構。編譯器將不知道該命令。 – tilz0R
如果你想創建一個供他人使用的庫,那麼總是創建一個*公共頭文件*,它定義庫的用戶所需要的東西。您不必定義完整的結構,而是可以執行類似標準的「FILE」不透明結構,您只需要'typedef struct library_socket_structure SOCKET;'。然後將*指針*傳遞給此函數的'SOCKET'類型名稱。 –
哦,你應該重新命名'SOCKET',因爲'SOCKET'也是Windows中的標準套接字類型。 –