我已经重新编写了一些libC函数,并将其合并到我的共享对象库中。其中一些函数在内部调用自己。
现在的问题是,当我从另一个程序中使用dlsym时,dlsym提供的函数(内部使用需要内部函数)将调用libC的函数,而不是我在库中重新编码的那些函数。
下面是一个简单的例子:
库c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void *memset(void *s, int c, size_t n)
{
  printf("Calling LIB's Memset\n");
  for (size_t i = 0; i < n; ++i)
    ((char *) s)[i]  = c;
  return s;
}

void *calloc(size_t mnemb, size_t size)
{
  size_t sz = mnemb * size;
  void *addr = malloc(sz);

  printf("Calling LIB's Calloc\n");
  memset(addr, 0, sz);
  return addr;
}

gcc lib.c -fPIC -shared -o lib.so
主c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main(void)
{
  void *handler = dlopen("./lib.so", RTLD_NOW);
  void (*_calloc)(size_t, size_t);

  if (!handler)
  {
    printf("Could not open lib\n");
    return 1;
  }
  _calloc = dlsym(handler, "calloc");
  if (!_calloc)
  {
    printf("Could not extract symbol\n");
    return 1;
  }
  _calloc(10, 10);
  return 0;
}

gcc main.c -ldl
$ ./a.out
Calling LIB's Calloc

如您所见,只有来自lib的calloc函数被调用,而内部的memset则不被调用。
在我的库中,我如何告诉它显式地调用自己的函数?
注意:我的函数的调用方式必须与libC相同,因为它也必须与LD_PRELOAD一起使用。

最佳答案

在我的库中,我如何告诉它显式地调用自己的函数?
最好的方法可能是给自己的函数起不同的名字。例如,在他们的名字前面加上一致的前缀:my_strlenmy_printf,等等。。然后,当库打算调用中的其他函数时,仅使用这些名称。愚蠢的例子:

size_t my_strlen(const char *s) {
    return *s ? (1 + my_strlen(s + 1)) : 0;
}

为了使外部调用者代替其名称来调用这些函数,插入包装函数。例如:
size_t strlen(const char *s) {
    return my_strlen(s);
}

但是,再一次,不要依赖图书馆里的包装纸。如果你愿意的话,你甚至可以把包装纸分成一个单独的库。
这里的想法是尽量减少你暴露在链接器游戏和动态链接效果。当需要替换自己的标准库函数实现时,您不能完全避免这些问题,但是这样可以减少它们给您带来麻烦的范围。

关于c - 共享对象本身显式调用内部函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48710571/

10-11 22:06
查看更多