私は汎用ソケット.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.c
がSOCKET
ためtypedef
「sのメインコードを下に乱雑にすることなく、socket_connect
の戻り値を格納できるようにsocket.so
からapplication.c
にSOCKET
情報を取得する - それは、すでにsocket.c
に一度行われていますので、。socket.h
がなくても、目標はヘッダーファイルの必要性を回避することだからです。- メインアプリケーションコード内
struct
/typedefの情報の潜在的に何百もの事前定義することなくライブラリ関数からの戻り値を処理するために、任意の代替方法。
これはOOPに向かって傾いていて、それは伝統的なCではないということです。これはCが嫌な人でも、醜い人物ではありません。そして、この質問がトピックの境界線であるか、またはすべてのプログラマーにこれまで怒っていたら、私は謝罪します。
を私はあなたがDLLから構造をインポートし、構造を知らなくても、後でそれをコンパイルすることができます信じていません。コンパイラは順序を知りません。 – tilz0R
他人が使用するライブラリを作成する場合は、ライブラリのユーザが必要とするものを定義する*パブリックヘッダファイル*を常に作成します。完全な構造を定義する必要はありません。代わりに、標準の 'FILE'不透明構造のようなことができます。 'typedef struct library_socket_structure SOCKET;'。関数のこの 'SOCKET'型名に*ポインタ*を渡します。 –
ああ、 'SOCKET'はWindowsの標準ソケットタイプなので、おそらく' SOCKET'の名前を変更するべきです。 –