是否可以包装 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 文件。在映射文件中,您应该能够找到所需函数的错位名称。
我正在尝试包装 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 文件。在映射文件中,您应该能够找到所需函数的错位名称。