Как передать/сделать объект/переменную доступной внутри функции обратного вызова, которая вызывается сторонней библиотекой?

Как сделать globalObject доступным для callbackFunction?

Я использую стороннюю библиотеку library.h, в которой есть метод libraryFunction. Результатом libraryFunction является libraryFunctionOutput, который передается в функцию обратного вызова callbackFunction.

Как передать другой объект (например, globalObject) для использования внутри функции обратного вызова callbackFunction?

К сожалению, сторонняя библиотека скомпилирована, поэтому я не могу внести в нее какие-либо изменения.

#include <stdio.h>
#include "library.h"

int callbackFunction(int libraryFunctionOutput):
    printf("%s, %d", libraryFunctionOutput, globalObject);
    return 1;

int main(int argc, char* argv[])
{
   int globalObject = 0;
   libraryFunction(callbackFunction);
}

В документации функция показана так:

int __stdcall libraryFunction(const char*    filename,
                              unsigned int   flags,
                              int            userID,
                              MathrelCallback callbackFunction);

Структура MathrelCallback определяется следующим образом:

struct MathrelCallback {MathrelHeader header;
                        MathrelInfo   data;
                        unsigned int Type;
};

person Community    schedule 08.10.2016    source источник
comment
Какая подпись у libraryFunction ? Если он принимает лямбда, ответ будет тривиальным. Не знаю, возможно ли это, если он принимает только указатели функций, кроме как путем копирования globalObject в глобальную переменную.   -  person Franck    schedule 08.10.2016
comment
Большинство API в стиле C также передают указатель контекста. Вы должны использовать это для контекста.   -  person krzaq    schedule 08.10.2016
comment
@Franck Я добавил, как выглядит библиотека в документации. Я не думаю, что он принимает лямбду. Я доволен globalObject в глобальной переменной, так как это относительно небольшое приложение. @krzaq К сожалению, внутри libraryFunction нельзя передавать никакие другие контекстные аргументы, кроме функции обратного вызова.   -  person    schedule 08.10.2016
comment
Можете ли вы опубликовать определение MathrelCallback? Я думаю, это просто указатель на функцию, но кто знает...   -  person Horstling    schedule 08.10.2016
comment
@Horstling Обновил пост, добавив определение MathrelCallback.   -  person    schedule 08.10.2016
comment
Хорошо, это определенно не простой обратный вызов. Трудно сказать, что вы можете сделать с этим без документации.   -  person Horstling    schedule 08.10.2016
comment
Я поговорю с провайдером в понедельник, ваше решение для глобальных переменных/объектов сработало отлично! Это было немного сложно, так как мне пришлось использовать другой сторонний пользовательский объект. Спасибо за вашу помощь!   -  person    schedule 08.10.2016


Ответы (1)


Если библиотека действительно принимает указатель на функцию (а не обобщенный Callable, такой как std::function) и не предлагает возможности передать контекст или указатель пользователя на ваш обратный вызов, вы должны сделать свой глобальный объект глобальным (со всеми его недостатками) :

#include <stdio.h>
#include "library.h"

static int globalObject = 0;

int callbackFunction(int libraryFunctionOutput)
{
    printf("%s, %d", libraryFunctionOutput, globalObject);
    return 1;
}

int main(int argc, char* argv[])
{
   libraryFunction(callbackFunction);
}
person Horstling    schedule 08.10.2016
comment
Будет ли это компилироваться? Я пытаюсь заставить небольшой пример работать, и я должен что-то упустить. : выглядит неуместно? - person wally; 08.10.2016
comment
Попробуйте изменить int main(int argcm char* argv[]) на int main(int argc, char* argv[]). - person ; 08.10.2016
comment
Ой, просто скопировал и отредактировал исходный код, даже не заметил ошибок. - person Horstling; 08.10.2016