当我尝试创建通用套接字.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
,但它是我想要实现的想法的一个例子)
或者在我的套接字库中使用init()
函数返回sizeof(SOCKET)
,以便我可以在malloc()
中使用application.c
为任何字节创建内存占位符{ {1}}需要在内存分配中手动完成。
由于我不认识任何人在C中探索这些东西 - 并且在线搜索线程似乎没有提供有关该主题的信息,除了将我链接到维基百科上的不同病毒类别。
或者某些threads完全避免了库函数的返回值。
所以我问一个模糊的问题,希望有人知道如何:
SOCKET
符号添加到符号树中来保留/显示链接器/编译器,以及如何使用struct SOCKET
或类似设置来设置它。 dlsym()
获取SOCKET
个信息至socket.so
,以便application.c
可以存储application.c
的返回值,而不必使主代码混乱socket_connect
的{{1}} - 因为typedef
已经完成了一次。没有SOCKET
- 因为目标是解决头文件的需求。socket.c
/ typedef信息。我知道这是倾向于OOP而且,它再次不是传统的C.它既丑陋又不是任何理智的人会做的事情,因为C是a。如果这个问题是临界主题或者冒犯每个程序员,我会道歉。
答案 0 :(得分: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 */