我正在C中构建一个由我没有源访问权限的程序动态加载的共享库.目标平台是64位Linux平台,我们正在使用gcc构建.我能够在~100行中构建问题的复制品,但仍有一点需要阅读.希望它是说明性的.
核心问题是我在共享库中定义了两个非静态函数(bar和baz).两者都需要是非静态的,因为我们希望调用者能够使用它们.另外,baz电话bar.正在使用我的库的程序也有一个名为的函数bar,这通常不是问题,但调用程序是用-rdynamic它编译的,因为它有一个foo需要在我的共享库中调用的函数.结果是我的共享库最终链接到bar运行时调用程序的版本,产生不直观的结果.
在理想的世界中,我可以在编译共享库时包含一些命令行开关,以防止这种情况发生.
我当前的解决方案是将我的非静态函数重命名为funname_local并将它们声明为静态.然后我定义一个新函数:
funname() { return funname_local(); },并将funname我共享库中的任何引用更改为funname_local.这有效,但感觉很麻烦,我更喜欢告诉链接器更喜欢本地编译单元中定义的符号.
internal.c
#include <stdio.h>
#include "internal.h"
void
bar(void)
{
printf("I should only be callable from the main program\n");
}
Run Code Online (Sandbox Code Playgroud)
internal.h
#if !defined(__INTERNAL__)
#define __INTERNAL__
void
bar(void);
#endif /* defined(__INTERNAL__) */
Run Code Online (Sandbox Code Playgroud)
main.c中
#include <dlfcn.h>
#include <stdio.h>
#include "internal.h"
void
foo(void)
{
printf("It's important that I am callable from both main …Run Code Online (Sandbox Code Playgroud) 我移植了ODBC从司机Windows到Linux.
驱动程序是写的C.工作
方式是应用程序调用ODBC管理器(),然后加载相应的驱动程序并传递函数调用. ODBCLinuxODBCM
假设我的驱动程序被编译成一个共享对象,它暴露了两个函数A和B.
应该发生的是ODBCMis调用函数A,函数A是调用函数B.
什么是实际发生的情况是,当函数A调用函数B而不是函数B'(具有相同的名称B,坐落在libodbc共享对象,并通过加载Linux使用ODBC的应用程序)被调用.
我觉得应该有编译时标志或后期编译库修改工具来纠正这个问题.
目前我正在通过库一次执行以下功能:
_B(){ // rename old functions
...
}
B() { // add new wrapper function
return _B(); // which just calls old
}
_A() {
...
_B(); // Change calls to renamed functions
...
}
Run Code Online (Sandbox Code Playgroud)
变化缓慢,感觉很糟糕.