有什么方法可以replace库中的函数吗?

我和一个图书馆一起工作,它定义了一个脚本语言的内部分工操作员。 不幸的是,它不会检查除数。 这导致很多头痛。 我知道运营商的签名。

double ScriptClass::Divide(double&, double&);

可悲的是,它甚至不是一个C函数。 有没有什么办法可以让我的应用程序使用我自己的Divide函数而不是ScriptClass::Divide函数?

编辑:我知道dlopen(NULL,..)并用用户定义的replace“C”function。 这可以做类成员函数(不诉诸使用mangled名称)?

Solutions Collecting From Web of "有什么方法可以replace库中的函数吗?"

一般来说,这取决于程序员,而不是基本的划分运算符来防止被零除。 如果你用零除很多,似乎表明在使用的算法中可能存在缺陷。 考虑修改算法,或者如果这不是一个选项,警卫呼叫将分成一个零检查。 你甚至可以在protected_divide类型的函数中做这个。

所有这一切,假设因为它看起来像一个C ++函数,你有一个C ++库编译与你用来建立你的应用程序的所有相同的选项,所以命名mangling匹配,你可能能够重新定义为一个。使用LD_PRELOAD强制它加载。 如果你静态链接,我认为你可以创建函数到你自己的.o文件中,并链接到库之前,链接器会自动获取你的版本。

正如其他人所提到的,各种链接器和动态链接器实现将提供看起来像这样的解决方案。

但是,如果您使用这些功能(GNU ld's –wrap,ld.so的LD_PRELOAD等)重新定义一个C ++函数, 则违反了单义定义规则 ,从而调用未定义的行为。

在编译你的库的时候,编译器可以用任何它认为合适的方式来内联这个函数,这意味着你可能不会在所有情况下调用函数的重定义。

考虑下面的代码:

 class A { public: void foo(); void bar(); }; void A::foo() { std::cout << "Old version.\n"; } void A::bar() { foo(); } 

当用-O3调用GCC 4.5时,实际上会决定将foo()的定义内联到bar()中。 如果你以某种方式让你的链接器用你自己的定义来替换A :: foo()的定义,那么A :: bar() 仍然会输出字符串“Old version。\ n”。

所以,一句话:不要。

我不这么认为,但是你可以使用ld的--wrap选项来使一个特定的函数根据它的旧名字得到一个新的名字。 然后,你可以写一个新的版本,如果你愿意,也可以转发到旧版本。

快速浏览:

http://linux.die.net/man/1/ld

我过去曾经使用过这个方法来挂钩到malloc (等),而不必重新编译运行时库,尽管这不在Linux上(这是一个嵌入式的东西,没有运行时加载)。 我没有用它来包装C ++函数,但是如果你能够以某种方式处理C ++调用约定,并且你可以使用原始函数的mangled名称来创建一个函数,并且让编译器接受一个函数的调用,名字有趣的字符在里面…我不明白为什么它不应该成为可能的工作。

只是简短的Q,不能用自己的代码包装类? 在开始的时候会比较头疼,但是比以后可以简化很多功能。

(或者甚至只是用宏来包装函数)