2017-07-27 12 views
1

私は汎用ソケット.soライブラリを作成しようとしたとき、私は好奇心旺盛です。私は、インポートし、application.cから使用しようインポート構造体 - ヘッダーファイルなしでコンパイル時に

## == 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; 
} 


私は構造体定義されたプラットフォームとのように見える機能を持っています。もちろん、私がここで以来、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を作ることができれば疑問に思い始めた、といくつかの方法は、コンパイル時にリンクされたヘッダファイルなしapplication.cでそれを設定します。

extern typedef int SOCKET;に似た何かをすることによって、それをロードするためにdlsym()を使用しますか。
externは明らかにmultiple storage classes in declaration specifiersで失敗しますが、それは私が達成しようとしているアイデアの一例です)

それとも、私が使用できるようにsizeof(SOCKET)を返された私のソケットライブラリでinit()機能を有することにより、malloc()application.cで、SOCKETがメモリ割り当てに必要な任意のバイトのメモリプレースホルダを作成し、手動で行います。私はCでこれらの事を探求しています誰にも分からないので

- とオンラインのスレッドを検索は、Wikipediaの異なるウイルスカテゴリに私をリンク除いトピックについての情報を与えないように見えます。
またはthreadsは、ライブラリ関数からの戻り値を完全に回避します。

は、だから私は、誰かが方法を知っていることを期待してあいまいな質問をしています:

  • キープ/は、シンボルツリーに追加することで、リンカ/コンパイラへstruct SOCKETシンボルを公開し、いくつかはdlsym()をどのように使用しますまたはそれを設定するために同様の。
  • application.cSOCKETためtypedef「sのメインコードを下に乱雑にすることなく、socket_connectの戻り値を格納できるようにsocket.soからapplication.cSOCKET情報を取得する - それは、すでにsocket.cに一度行われていますので、。 socket.hがなくても、目標はヘッダーファイルの必要性を回避することだからです。
  • メインアプリケーションコード内struct/typedefの情報の潜在的に何百もの事前定義することなくライブラリ関数からの戻り値を処理するために、任意の代替方法。

これはOOPに向かって傾いていて、それは伝統的なCではないということです。これはCが嫌な人でも、醜い人物ではありません。そして、この質問がトピックの境界線であるか、またはすべてのプログラマーにこれまで怒っていたら、私は謝罪します。

+0

を私はあなたがDLLから構造をインポートし、構造を知らなくても、後でそれをコンパイルすることができます信じていません。コンパイラは順序を知りません。 – tilz0R

+0

他人が使用するライブラリを作成する場合は、ライブラリのユーザが必要とするものを定義する*パブリックヘッダファイル*を常に作成します。完全な構造を定義する必要はありません。代わりに、標準の 'FILE'不透明構造のようなことができます。 'typedef struct library_socket_structure SOCKET;'。関数のこの 'SOCKET'型名に*ポインタ*を渡します。 –

+0

ああ、 'SOCKET'はWindowsの標準ソケットタイプなので、おそらく' SOCKET'の名前を変更するべきです。 –

答えて

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 */ 
関連する問題