我正在尝试在 macOS 上的动态库内的 C 结构中插入声明为指针的函数。
我在 libA.dylib 中有这个结构:
libA.h:
typedef struct AStruct {
int (*sub)(AStruct *pAStruct, int a, int b);
} AStruct;
extern "C" AStruct * AStruct_new();
libA.cpp:
int sub(AStruct *pAStruct, int a, int b) {
return a - b;
}
AStruct * AStruct_new() {
AStruct *pAStruct = (AStruct *)malloc(sizeof(AStruct));
pAStruct->sub = *sub;
return pAStruct;
}
名称修改后,我发现库中对应的名称是这样的:_Z3subP7AStructii
在我的dylib(我将其注入(inject)客户端代码中)中,我正在这样做:
typedef struct AStruct {
int (*sub)(AStruct *pAStruct, int a, int b);
} AStruct;
extern "C" int _Z3subP7AStructii(AStruct *pAStruct, int a, int b);
int _sub(AStruct *pAStruct, int a, int b) {
printf("interposed %s: ", __func__);
return pAStruct->sub(pAStruct, a, b);
} DYLD_INTERPOSE(_sub, _Z3subP7AStructii)
DYLD_INTERPOSE
- 是 Apple 的宏,来自 here
相同的代码成功地适用于常规 C 函数、C++ 静态/实例方法,但无法弄清楚结构内的函数指针有什么问题:(
最佳答案
如果我理解正确的话,您希望对 sub
(或更确切地说 _Z3subP7AStructii
)的所有调用实际上都调用您的 _sub
函数吗?问题是,当“客户端”调用 some_astruct->sub(...)
时,它实际上并没有直接调用 _Z3subP7AStructii
,因此你的 _sub
函数不会被调用。
换句话说,“客户端”没有调用 _Z3subP7AStructii
,而是调用了 some_astruct->sub
所指向的内容。 _Z3subP7AStructii
函数甚至无法由 libA
库导出(即与 static
等具有内部链接),但仍然可以通过结构。
对此的一个可能的解决方案是不“插入”sub
函数,而是“插入”AStruct_create
函数。在您的版本中调用原始版本,然后将结构中指向 sub
函数的指针替换为您自己的函数(可能保存原始版本以便您可以使用它)。
关于c++ - 插入C结构函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53535716/