2017-07-27 61 views
1

當我試圖創建一個通用套接字庫.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.soSOCKET信息application.c使application.c可以存儲socket_connect返回值,而不必與typedef的雜亂下跌爲主代碼SOCKET - 因爲這已經在socket.c做一次。沒有socket.h - 因爲我們的目標是解決對頭文件的需求。
  • 任何替代的方式來處理從庫函數返回值而不定義預潛在數百在主應用程序代碼struct/typedef的信息。

我知道這是傾向於面向對象,並且它不是傳統的C.它既醜陋又不是任何人都會理智的,因爲C是一個人。我很抱歉,如果這個問題是邊界線題外話或冒犯每一位程序員。

+0

我不相信你可以從DLL進口結構,後來編譯它不知道結構。編譯器將不知道該命令。 – tilz0R

+0

如果你想創建一個供他人使用的庫,那麼總是創建一個*公共頭文件*,它定義庫的用戶所需要的東西。您不必定義完整的結構,而是可以執行類似標準的「FILE」不透明結構,您只需要'typedef struct library_socket_structure SOCKET;'。然後將*指針*傳遞給此函數的'SOCKET'類型名稱。 –

+0

哦,你應該重新命名'SOCKET',因爲'SOCKET'也是Windows中的標準套接字類型。 –

回答

0

我不認爲dlopen的有什麼用此...如果你想有一個獨立於平臺的插座模塊,試一下這個:

/* ownsocket.h */ 

/* opaque type-definition */ 
typedef struct OwnSocket OwnSocket; 

/* constructors */ 
OwnSocket *newServerSocket (int port); 
OwnSocket *newClientSocket (const char *ptnhost, int ptnport); 
OwnSocket *acceptClient (OwnSocket *server); 
/* other constructors */ 
... 
/* destructor */ 
closeSocket (OwnSocket *); 

/* other operations */ 

然後:

/* ownsocket.c */ 

#include "ownsocket.h" 

struct OwnSocket { 
    int type; /* -1/0/1/2 = closed/client/listening_server/sub_server */ 
    ... 
#ifdef __unix__ 
    int handle; 
#else 
    SOCKET handle; 
#endif 
    ... 
}; 

/* implementation of functions */ 
相關問題