Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 拦截C调用并将其转发到第三方库_C++_C_Linux_Macos - Fatal编程技术网

C++ 拦截C调用并将其转发到第三方库

C++ 拦截C调用并将其转发到第三方库,c++,c,linux,macos,C++,C,Linux,Macos,我有一个调用第三方共享库(C)的应用程序(A)。我想写一个我自己的库(B),截取从a到C的调用,在某些情况下用我自己的代码替换调用,在某些情况下做一些额外的处理,然后在C中调用匹配函数,在某些情况下直接将调用转发给C 该应用程序是开源的,因此我可以更改每个调用站点,在B中调用一个类似命名的函数,然后在需要时在C中调用相应的函数,但这将需要大量的工作,并且会使合并应用程序中的上游更改变得困难。我没有第三方库的源代码。如果它是header-only,那么我就可以使用名称空间来实现这一点,但我不知道如

我有一个调用第三方共享库(C)的应用程序(A)。我想写一个我自己的库(B),截取从a到C的调用,在某些情况下用我自己的代码替换调用,在某些情况下做一些额外的处理,然后在C中调用匹配函数,在某些情况下直接将调用转发给C

该应用程序是开源的,因此我可以更改每个调用站点,在B中调用一个类似命名的函数,然后在需要时在C中调用相应的函数,但这将需要大量的工作,并且会使合并应用程序中的上游更改变得困难。我没有第三方库的源代码。如果它是header-only,那么我就可以使用名称空间来实现这一点,但我不知道如何进行,因为我的库和第三方库似乎都需要定义完全相同的符号


有什么办法可以让这一切顺利吗?我主要针对OSX,但希望它能在linux上工作,然后最终也能在Windows上工作

您可以使用LD_PRELOAD指向您自己的共享库。使用LD_PRELOAD,将调用共享库中的所有函数,而不是调用其他库中具有相同名称的函数

如果您希望注入代码,然后调用原始函数,则需要调用dlsym以从第三方库获取原始函数


这里有一些例子:

一个解决方案如下

在头文件中,
#定义要拦截到包装函数的所有函数

#define foo wrap_foo
#define bar wrap_bar
将其粘贴到任何地方都包含的头文件中,以便所有代码都包含此头文件。此标头应包含在正在拦截的库的标头之前
gcc
还有一个
-include
选项,该选项使头文件包含在所有源中

这里的目标是将所有对实际函数的调用替换为对包装器函数的调用

#define foo wrap_foo
#define bar wrap_bar
现在在某处定义包装函数,并根据需要拦截调用。此文件不应包含您先前创建的包装头

int wrap_foo() {
    return foo();
}

int wrap_bar() {
    return bar();
}
把它联系起来


请注意,这将允许您仅在编译的代码(包括包装头)中拦截对
foo()
bar()
等的调用。任何预编译的代码(在库或对象中)都将直接链接到
foo()
bar()
等。

您还没有说明正在使用的工具链。不知道其他的工具链,但是GNULD有
--wrap
选项,这是实现所需的一种方法。从描述的
--wrap symbol
:“为symbol使用包装函数。任何未定义的对symbol的引用都将解析为uu wrap_symbol。任何未定义的对uu real_symbol的引用都将解析为symbol。这可以用于为系统函数提供包装。”这是可行的,我做到了:)但需要大量的工作。基本上,您必须从.o文件中提取符号信息,并用您创建的“thunk”替换所有未定义的符号。诀窍是保留参数,在通常情况下,对于未知函数,您必须在ASM中执行thunk。是否使用
#define
来转移库函数调用?例如
#define strchr mystrchr
至少LD_PRELOAD在Linux上可以工作,我不能肯定在OS X上工作。谢谢,好主意!虽然这在应用程序中是入侵性的,但我应该能够以一种使合并无缝的方式进行。