首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用共享对象中定义的C函数,而不重命名它们

使用共享对象中定义的C函数,而不重命名它们
EN

Stack Overflow用户
提问于 2013-07-23 00:32:20
回答 1查看 373关注 0票数 0

我一直在阅读在线书籍Basics of libuv,并尝试重写它们以同时使用到libuv库的静态链接和动态链接。我重写了the watchers example (下面的代码),但我必须“重命名”从libuv.dylib检索到的函数才能使其工作,这意味着我必须为动态链接情况编写一个完全不同的代码路径。我能以某种方式保持相同的函数名吗?

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

代码语言:javascript
复制
#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;
}

目前,它看起来像这样。

代码语言:javascript
复制
#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;
}
EN

回答 1

Stack Overflow用户

发布于 2013-07-23 05:54:01

更改:

代码语言:javascript
复制
#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
/*...*/

进入:

代码语言:javascript
复制
#ifndef DYNAMIC
#include <uv.h>
#else
#include <dlfcn.h>
/*...*/

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

然而,还不清楚为什么你需要这样做。通常,您只需将应用程序与动态库链接即可。如果您正在试验性地更改动态库的实现(将其视为插件),则只需执行您正在做的操作。

在注释中,您提到需要<uv.h>中的结构定义。然后,要使我最初的建议生效,您需要在DYNAMIC的情况下重新定义这些结构,因为您不会使用头文件。但是,如果uv库发生更改,您将丢失这些更改,并被迫更新您的DYNAMIC版本以与之匹配,这是一种不受欢迎的情况。

另一种变通方法是按照原来的方法定义不同的函数指针名称,然后定义宏来将原始函数名称映射到函数指针名称。

代码语言:javascript
复制
#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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17792805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档