Я думаю, что папка с ресурсами общедоступна, вы можете получить к ней доступ непосредственно в браузере
http: // localhost: 4020 / assets /
в отличие от других приватных папок, отбросьте свой json-файл в папку с ресурсами
Как вы теперь показали, ваша функция init принимает не-членную функцию. так что сделайте это так:
static void Callback(int other_arg, void * this_pointer) {
CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
self->RedundencyManagerCallBack(other_arg);
}
и вызовите Init с
m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);
Это работает, потому что указатель функции на статическую функцию-член не является указателем на функцию-член и может таким образом обрабатываться как указатель на свободную функцию.
Доступна ли функция m_cRedundencyManager
для использования функций-членов? Большинство обратных вызовов настроены на использование регулярных функций или статических функций-членов.
Обновление: Объявление функции, которое вы указали, показывает, что m_cRedundencyManager
ожидает, что функция вида: void yourCallbackFunction(int, void *)
. Поэтому функции-члены неприемлемы как обратные вызовы в этом случае. Статическая функция-член может работать, но если это неприемлемо в вашем случае, будет работать и следующий код. Обратите внимание, что он использует злое действие из void *
.
// in your CLoggersInfra constructor:
m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);
// in your CLoggersInfra header:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);
// in your CLoggersInfra source file:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)
{
((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);
}
Указатель на функцию-член класса не совпадает с указателем на функцию. Член класса принимает неявный дополнительный аргумент (указатель этого ) и использует другое соглашение о вызове.
Если ваш API ожидает функцию обратного вызова без ответа, это то, что вам нужно пройти к нему.
Какой аргумент делает Init
? Какое новое сообщение об ошибке?
Указатели метода на C ++ немного сложны в использовании. Помимо самого указателя метода, вам также необходимо указать указатель экземпляра (в вашем случае this
). Может быть, Init
ожидает, что это будет отдельный аргумент?
Я вижу, что init имеет следующее переопределение:
Init (CALLBACK_FUNC_EX callback_func, void * callback_parm)
, где CALLBACK_FUNC_EX is typedef void (* CALLBACK_FUNC_EX) (int, void *); [/ д2]
Этот вопрос и ответ из C ++ FAQ Lite охватывает ваш вопрос и соображения, связанные с ответом, довольно красиво, я думаю. Короткие фрагменты с веб-страницы, с которой я связан:
Do not.
Поскольку функция-член бессмысленна, если объект не вызывает его, вы не можете этого сделать (если система X Window была переписана на C ++, она, вероятно, передавала бы ссылки на объекты, а не только указатели на функции, естественно, объекты воплотили бы требуемую функцию и, вероятно, намного больше).
Этот ответ является ответом на комментарий выше и не работает с VisualStudio 2008, но должен быть предпочтительнее с более поздними компиляторами.
Между тем вам больше не нужно использовать указатель void и нет необходимости в усилении, так как доступны std::bind
и std::function
. Преимущество одного (по сравнению с указателями void) - это безопасность типа, поскольку тип возврата и аргументы явно указаны с помощью std::function
:
// std::function<return_type(list of argument_type(s))>
void Init(std::function<void(void)> f);
Затем вы можете создать функцию указатель с std::bind
и передать его Init:
auto cLoggersInfraInstance = CLoggersInfra();
auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
Init(callback);
Полный пример для использования std::bind
с членами, статическими членами и не-членными функциями:
#include <functional>
#include <iostream>
#include <string>
class RedundencyManager // incl. Typo ;-)
{
public:
// std::function<return_type(list of argument_type(s))>
std::string Init(std::function<std::string(void)> f)
{
return f();
}
};
class CLoggersInfra
{
private:
std::string member = "Hello from non static member callback!";
public:
static std::string RedundencyManagerCallBack()
{
return "Hello from static member callback!";
}
std::string NonStaticRedundencyManagerCallBack()
{
return member;
}
};
std::string NonMemberCallBack()
{
return "Hello from non member function!";
}
int main()
{
auto instance = RedundencyManager();
auto callback1 = std::bind(&NonMemberCallBack);
std::cout << instance.Init(callback1) << "\n";
// Similar to non member function.
auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
std::cout << instance.Init(callback2) << "\n";
// Class instance is passed to std::bind as second argument.
// (heed that I call the constructor of CLoggersInfra)
auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
CLoggersInfra());
std::cout << instance.Init(callback3) << "\n";
}
Возможный выход:
Hello from non member function!
Hello from static member callback!
Hello from non static member callback!
Кроме того, используя std::placeholders
, вы можете динамически передавать аргументы для обратного вызова (например, это позволяет использовать return f("MyString");
в Init
, если f имеет строковый параметр).