先看下用例源码:
main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <uv.h>
#include "plugin.h"
typedef void (*init_plugin_function)();
void mfp_register(const char *name) {
fprintf(stderr, "Registered plugin \"%s\"\n", name);
}
int main(int argc, char **argv) {
if (argc == 1) {
fprintf(stderr, "Usage: %s [plugin1] [plugin2] ...\n", argv[0]);
return 0;
}
uv_lib_t *lib = (uv_lib_t*) malloc(sizeof(uv_lib_t));
while (--argc) {
fprintf(stderr, "Loading %s\n", argv[argc]);
if (uv_dlopen(argv[argc], lib)) {
fprintf(stderr, "Error: %s\n", uv_dlerror(lib));
continue;
}
init_plugin_function init_plugin;
if (uv_dlsym(lib, "initialize", (void **) &init_plugin)) {
fprintf(stderr, "dlsym error: %s\n", uv_dlerror(lib));
continue;
}
init_plugin();
}
return 0;
}
hello.c
#include "plugin.h"
void initialize() {
mfp_register("Hello World!");
}
plugin.h
#ifndef UVBOOK_PLUGIN_SYSTEM
#define UVBOOK_PLUGIN_SYSTEM
// Plugin authors should use this to register their plugins with mfp.
void mfp_register(const char *name);
#endif
功能很简单:载入启动参数中对应的插件动态库,调用它们的 initialize 方法
看下结构体:1个函数指针 一个错误消息指针
typedef struct {
void* handle;
char* errmsg;
} uv_lib_t;
然后看下实现:
static int uv__dlerror(uv_lib_t* lib);
// 连接动态库 得到引用句柄
int uv_dlopen(const char* filename, uv_lib_t* lib) {
dlerror(); /* Reset error status. */
lib->errmsg = NULL;
lib->handle = dlopen(filename, RTLD_LAZY);
return lib->handle ? 0 : uv__dlerror(lib);
}
void uv_dlclose(uv_lib_t* lib) {
uv__free(lib->errmsg);
lib->errmsg = NULL;
if (lib->handle) {
/* Ignore errors. No good way to signal them without leaking memory. */
dlclose(lib->handle);
lib->handle = NULL;
}
}
// 获取句柄指定方法 注意第三个参数 修改指传入ptr指针所指向 函数指针
int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) {
dlerror(); /* Reset error status. */
*ptr = dlsym(lib->handle, name);
return uv__dlerror(lib);
}
const char* uv_dlerror(const uv_lib_t* lib) {
return lib->errmsg ? lib->errmsg : "no error";
}
static int uv__dlerror(uv_lib_t* lib) {
const char* errmsg;
uv__free(lib->errmsg);
errmsg = dlerror();
if (errmsg) {
lib->errmsg = uv__strdup(errmsg);
return -1;
}
else {
lib->errmsg = NULL;
return 0;
}
}
总结:主要就是演示如何使用动态加载库。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。