是否可以包装 C++ class 的成员函数?

Is it possible to wrap a member function of a C++ class?

我正在尝试包装 C++ 的成员函数 class。我已经成功包装了系统函数,例如 fstat,因此 GNU 链接器 ld 创建了对 __wrap_fstat 的引用和真正的 fstat 由 __real_fstat 调用,但我似乎无法包装 class 成员函数。这是 class 的一个简单示例。我想包装 test().

Foo.hpp

class Foo
{
public:
    Foo() {};
    ~Foo() {};
    void test();
}

Foo.cpp

#include "Foo.hpp"

void Foo::test()
{
    printf("test\n");
}

我试过了

g++ -o foo Foo.o -Wl,--wrap=Foo::test

链接器未产生错误,但未包装 test()。有谁知道如何包装 C++ class 成员函数?

在 C++ 中,所有符号名称都得到 mangled 以确保符号名称的唯一性,当函数名称被重载时,放置在 类 或 sub类 中,在名称空间内等.

链接器不知道 C++ 原始符号名称,只处理错位的符号名称。所以要包装 C++ 成员函数,您必须包装损坏的函数名称。

Foo.hpp

class Foo
{
public:
    Foo() {};
    ~Foo() {};
    void test();
};

Foo.cpp

#include "Foo.hpp"
#include <cstdio>

void Foo::test()
{
   printf("Original Foo:test(): this = %p\n", (void*)this);
}

main.cpp

#include "Foo.hpp"
#include <cstdio>

extern "C" void __real__ZN3Foo4testEv(Foo* This);

extern "C" void __wrap__ZN3Foo4testEv(Foo* This)
{
    printf("Wrapped Foo:test(): this = %p\n", (void*)This);
    __real__ZN3Foo4testEv(This);
}

int main()
{
    Foo foo;
    printf("Address of foo: %p\n", (void*)&foo);
    foo.test();
}

用法:

$ g++ -o foo main.cpp Foo.cpp -Wl,--wrap=_ZN3Foo4testEv; ./foo
Address of foo: 0xffffcc2f
Wrapped Foo:test(): this = 0xffffcc2f
Original Foo:test(): this = 0xffffcc2f

注意包装函数的签名__wrap__ZN3Foo4testEv:它需要声明extern "C"以避免自身被破坏。它可以访问 this 作为第一个隐式参数。 如果需要调用原函数,同样适用于real函数的声明__real__ZN3Foo4testEv.

要找出 C++ 函数的损坏名称,有几种方法。一个将包括首先构建项目而不包装,然后从链接器创建一个 map 文件。在映射文件中,您应该能够找到所需函数的错位名称。