gpt4 book ai didi

c - 使用共享库中定义的 C 函数而不重命名它们

转载 作者:太空宇宙 更新时间:2023-11-04 08:54:51 26 4
gpt4 key购买 nike

我一直在看网络书Basics of libuv并尝试重写它们以同时使用静态链接和指向 libuv 库的动态链接。我重写了the watchers example (下面的代码),但我不得不“重命名”我从 libuv.dylib 检索到的函数以使其工作,这意味着我必须为动态链接案例编写一个完全独立的代码路径。我能否以某种方式保留相同的函数名称?

我希望我的代码看起来像这样。

#include <stdio.h>
#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
#endif

int64_t counter = 0;

void wait_for_a_while(uv_idle_t *handle, int status) {
counter++;
if (counter >= 10e6)
uv_idle_stop(handle); // This function pointer must be a global variable
}

int main(int argc, char **argv) {
uv_idle_t idler;

// Initialize code needed for dynamically-linked library
#ifdef DYNAMIC
void *lib_handle = dlopen("libuv.dylib", RTLD_LOCAL|RTLD_LAZY);
// Set up pointers to functions defined in libuv.dyld ...
#endif

uv_idle_init(uv_default_loop(), &idler);
uv_idle_start(&idler, wait_for_a_while);

printf("Idling...\n");
uv_run(uv_default_loop(), UV_RUN_DEFAULT);

// Clean up dynamically linked code
#ifdef DYNAMIC
dlclose(lib_handle);
#endif
return 0;
}

目前,它看起来像这样。

#include <stdio.h>
#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
// Currently, I need to define function pointers with different names
// than the functions they call
uv_loop_t* (*uln)(void);
int (*ur)(uv_loop_t*, uv_run_mode);
uv_loop_t* (*udl)(void);
int (*uii)(uv_loop_t*, uv_idle_t*);
int (*uist)(uv_idle_t*, uv_idle_cb);
int (*uisp)(uv_idle_t*);
#endif

int64_t counter = 0;

void wait_for_a_while(uv_idle_t *handle, int status) {
counter++;
if (counter >= 10e6)
#ifdef DYNAMIC
uisp(handle);
#else
uv_idle_stop(handle); // This should be the only line remaining
#endif
}

int main(int argc, char **argv) {
uv_idle_t idler;

// Code path for dynamic linking case
#ifdef DYNAMIC
void *lib_handle = dlopen("libuv.dylib", RTLD_LOCAL|RTLD_LAZY);
// Retrieve symbol names from libuv.dylib
*(void **)(&uln) = dlsym(lib_handle, "uv_loop_new");
*(void **)(&ur) = dlsym(lib_handle, "uv_run");
*(void **)(&udl) = dlsym(lib_handle, "uv_default_loop");
*(void **)(&uii) = dlsym(lib_handle, "uv_idle_init");
*(void **)(&uist) = dlsym(lib_handle, "uv_idle_start");
*(void **)(&uisp) = dlsym(lib_handle, "uv_idle_stop");

uii(udl(), &idler);
uist(&idler, wait_for_a_while);

printf("Idling...\n");
ur(udl(), UV_RUN_DEFAULT);

dlclose(lib_handle);

// Code for static linking case
#else
uv_idle_init(uv_default_loop(), &idler);
uv_idle_start(&idler, wait_for_a_while);

printf("Idling...\n");
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
#endif
return 0;
}

最佳答案

改变:

#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
/*...*/

进入:

#ifndef DYNAMIC
#include <uv.h>
#else
#include <dlfcn.h>
/*...*/

现在,您可以将函数指针变量命名为与调用它们的接口(interface)相同的名称。

但是,目前还不清楚您为什么需要这样做。通常,您只需将您的应用程序与动态库链接起来。如果您正在试验性地更改动态库的实现(将其视为插件),则只需做您正在做的事情。


在评论中,您提到您需要 <uv.h> 中的结构定义.然后,为了使我的原始提案生效,您需要在 DYNAMIC 的情况下重新定义这些结构。 ,因为您不会使用头文件。但是,如果 uv库不断变化,您将丢失这些更改并被迫更新您的 DYNAMIC版本匹配,这是一种不希望出现的情况。

另一种解决方法是遵循您定义不同函数指针名称的原始方法,但随后定义宏以将原始函数名称映射到函数指针名称。

#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
uv_loop_t* (*uln)(void);
int (*ur)(uv_loop_t*, uv_run_mode);
//...
#define uv_loop_new uln
#defin uv_run ur
//...
#endif

关于c - 使用共享库中定义的 C 函数而不重命名它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17792805/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com