Вставить указатель на функцию структуры C - PullRequest
0 голосов
/ 29 ноября 2018

Я пытаюсь вставить функцию, объявленную как указатель, в структуру C внутри динамической библиотеки в macOS.

У меня есть эта структура в 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(который я внедряю в код клиента) я делаю это:

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 от здесь

того же кодауспешно работает для обычной функции C, статических методов / экземпляров C ++, не может понять, что не так с указателем на функцию внутри структуры: (

1 Ответ

0 голосов
/ 29 ноября 2018

Если я правильно понимаю, вы хотите, чтобы все вызовы sub (или, скорее, _Z3subP7AStructii) фактически вызывали вместо этого вашу функцию _sub?Проблема в том, что когда «клиент» вызывает some_astruct->sub(...), он на самом деле не вызывает _Z3subP7AStructii напрямую, и, следовательно, ваша _sub функция вызываться не будет.

Другими словами, «клиент»msgstr "нет вызова на _Z3subP7AStructii, но вместо этого есть вызов на то, на что указывает some_astruct->sub.Функция _Z3subP7AStructii может даже не экспортироваться библиотекой libA (т.е. иметь внутреннюю связь, например, с static), и ее все равно можно вызывать через структуру.

Возможное решение этой проблемы:не "вставлять" функцию sub, а вместо этого функцию AStruct_create.В вашей версии вызовите оригинал, а затем замените указатель на функцию sub в структуре на вашу собственную функцию (возможно, сохраните оригинал, чтобы вы могли использовать его).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...