I am trying to declare a class-member function pointer as static so it can be called by a static member function, and assign the pointer to a function passed to the constructor.
So far I haven't been able to get it working, is this somehow possible?
#include <stdio.h>
//external callback function
static void innerFunc(int i, float f){
printf("running inner function : %i %f\n", i, f);
}
class A{
// member function pointer
typedef void (A::*cbPtr)(int, float);
static cbPtr cbptr;
public:
//constructor
A(void(*func)(int, float))
{
A::cbptr = func; // < this doesn't work
}
void run()
{
memberFunc(5, 4.4, NULL, NULL);
}
private:
// static member function
static void memberFunc(int i, float f, void* a, const void* aa)
{
printf("running outer function.\n");
// cbptr(i, f); // << I want to be able to call the function here
}
};
int main() {
A a(innerFunc);
a.run();
return 0;
}
The A::cbPtr type expects a pointer to a non-static member function of the A class. But you are trying to assign a pointer to a non-member function to your static cbptr variable. They are two different types, that is why the code does not compile.
Drop the A:: from your cbPtr typedef, eg:
#include <stdio.h>
//external callback function
static void innerFunc(int i, float f)
{
printf("running inner function : %i %f\n", i, f);
}
class A
{
public:
// non-member function pointer
typedef void (*cbPtr)(int, float);
//constructor
A(cbPtr func)
{
m_cbptr = func;
}
void run()
{
memberFunc(5, 4.4, NULL, NULL);
}
private:
static cbPtr m_cbptr;
// static member function
static void memberFunc(int i, float f, void* a, const void* aa)
{
printf("running outer function.\n");
m_cbptr(i, f);
}
};
A::cbPtr A::m_cbptr = NULL;
int main()
{
A a(innerFunc);
a.run();
return 0;
}
When you learn how to separate your declarations and definitions into .h and .cpp files, it would look more like this instead:
A.h:
#ifndef A_H
#define A_H
class A
{
public:
// non-member function pointer
typedef void (*cbPtr)(int, float);
//constructor
A(cbPtr func);
void run();
private:
static cbPtr m_cbptr;
// static member function
static void memberFunc(int i, float f, void* a, const void* aa);
};
#endif
A.cpp:
#include "A.h"
#include <stdio.h>
A::cbPtr A::m_cbptr = NULL;
A::A(A::cbPtr func)
{
m_cbptr = func;
}
void A::run()
{
memberFunc(5, 4.4, NULL, NULL);
}
void A::memberFunc(int i, float f, void* a, const void* aa)
{
printf("running outer function.\n");
m_cbptr(i, f);
}
main.cpp:
#include "A.h"
#include <stdio.h>
//external callback function
static void innerFunc(int i, float f)
{
printf("running inner function : %i %f\n", i, f);
}
int main()
{
A a(innerFunc);
a.run();
return 0;
}
Either way, just know that because m_cbptr is static, multiple instances of A will share the same variable, so you won't be able to have separate callbacks for different A objects. If memberFunc() were not static, or if its a or aa parameter is a user-defined value that can be set to point at the A object's this pointer, then you can have a separate callback per object.
Related
I inherited a large rather-old C++98 codebase which is now luckily using C++17. I have an interface in a header file interfaceHeader.h as follows:
struct PluginInterface {
void (*method1)(bool enabled);
void (*method2)(int param1, int param2);
bool (*method3)(const char *path, const int& val);
};
then in another source cpp file:
MyImplementingClass *gClass = new gClass();
void method1(bool enabled) {
gClass->method1(enabled);
}
void method2(int p1, int p2) {
gClass->method2(p1, p2);
}
bool method3(const char *path, const int& val) {
return gClass->method3(path, val);
}
void pupulateInterface(PluginInterface& iface) {
iface.method1 = method1;
iface.method1 = method2;
iface.method1 = method3;
...
}
I don't have control over that global variable nor on the fact that the interface must be a struct of function pointer.
How can I reduce the boilerplate here? I tried using std::bind but it didn't work: a std::function cannot be converted to a C function pointer.
void pupulateInterface2(PluginInterface& iface) {
iface.method1 = [](bool enabled){
gClass->method1(enabled);
};
iface.method2 = [](int param1, int param2){
gClass->method2(param1,param2);
};
iface.method3 = [](const char *path, const int& val){
return gClass->method3(path, val);
};
}
I am trying to integrate a member function of a class, and needs some help! I cannot declare the function static because this function uses non-static private members (more specifically use a private member which is another class). I am using C++17 and cannot downgrade
I write below a Minimum (Non) Working Example that mimic my problem. The aim is to find what to put instead of the four question marks '????' in alglib::autogkintegrate(s, ????, params).
The alglib::autogkintegrate function takes three arguments:
a 'state' which contains the current value of the integration, integral boundaries, other stuff?)
The function f to integrate which must be of the prototype void f(double x, double xminusa, double bminusx, double &y, void *ptr)
an optional pointer void *ptr which contains extra parameters for the function f
Here is the non working example:
#include <functional>
#include <iostream>
#include <cmath>
#include "integration.h"
class Foo;
class Bar;
/*****************************
Class Foo
*****************************/
class Foo
{
public:
// Constructor
Foo(Bar *b, int toto);
// Function to integrate
void f(double x, double xminusa, double bminusx, double &y, void *ptr);
private:
Bar *m_bar;
int m_toto;
};
Foo::Foo(Bar *b, int toto) : m_bar(b), m_toto(toto)
{}
void Foo::f(double x, double xminusa, double bminusx, double &y, void *ptr)
{
double *param = (double *) ptr;
double p1 = param[0];
double p2 = param[1];
y = exp(this->m_toto*x)/(p1 * p2);
}
/*****************************
Class Bar
*****************************/
class Bar
{
friend Foo;
public:
// Constructor
Bar();
private:
int m_a, m_b;
};
Bar::Bar() : m_a(2), m_b(5)
{}
/*****************************
Main program
*****************************/
int main(int argc, char *argv[])
{
Bar* b = new Bar();
Foo f(b, 87);
double arrayParams[2] = {1, 2};
double (*params)[2] = &arrayParams;
alglib::autogkstate s;
double v;
alglib::autogkreport rep;
alglib::autogksmooth(0, 1, s);
alglib::autogkintegrate(s, ????, params);
alglib::autogkresults(s, v, rep);
return 0;
}
If I declare the function f as static (and remove this->m_totoin f), then I can integrate fby using alglib::autogkintegrate(s, Foo::f, params);. So the problem is really to get access to the function f.
I tried to define a pointer to member function (which explains #include <functional>) but failed to use it in alglib::autogkintegrate(s, ????, params);
To repeat my question: I want to integrate a member function of a class using ``Alglib``` in C++
Useful links:
https://www.alglib.net/translator/man/manual.cpp.html#gs_using section 8.5
https://www.alglib.net/translator/man/manual.cpp.html#example_autogk_d1
P.S.: I also posted this question at http://forum.alglib.net/viewtopic.php?f=2&t=4352 which is a dedicated forum to Alglib (but looks much less active than Stack Overflow, hence my double post. If I get an answer there, I will copy-paste here, and vice-versa)
I found a solution on http://www.newty.de/fpt/callback.html using a global variable (sorry...). I post here the code adapted to my question if anyone needs it:
#include <functional>
#include <iostream>
#include <cmath>
#include "integration.h"
class Foo;
class Bar;
void* pt2Object; // global variable which points to an arbitrary object
/*****************************
Class Foo
*****************************/
class Foo
{
public:
// Constructor
Foo(Bar *b, int toto);
// Function to integrate
void f(double x, double xminusa, double bminusx, double &y, void *ptr);
// Wrapper
static void Wrapper_To_Call_f(double x, double xminusa, double bminusx, double &y, void *ptr);
private:
Bar *m_bar;
int m_toto;
};
Foo::Foo(Bar *b, int toto) : m_bar(b), m_toto(toto)
{}
void Foo::f(double x, double xminusa, double bminusx, double &y, void *ptr)
{
double *param = (double *) ptr;
double p1 = param[0];
double p2 = param[1];
y = exp(this->m_toto*x)/(p1 * p2);
// y = exp(x)/(p1 * p2);
}
void Foo::Wrapper_To_Call_f(double x, double xminusa, double bminusx, double &y, void *ptr)
{
// explicitly cast global variable <pt2Object> to a pointer to TClassB
// warning: <pt2Object> MUST point to an appropriate object!
Foo* mySelf = (Foo*) pt2Object;
// call member
mySelf->f(x, xminusa, bminusx, y, ptr);
}
/*****************************
Class Bar
*****************************/
class Bar
{
friend Foo;
public:
// Constructor
Bar();
private:
int m_a, m_b;
};
Bar::Bar() : m_a(2), m_b(5)
{}
/*****************************
Main program
*****************************/
int main(int argc, char *argv[])
{
Bar* b = new Bar();
// Create Foo
Foo myFoo(b, 1);
// Assign global variable which is used in the static wrapper function
// important: never forget to do this!!
pt2Object = (void*) &myFoo;
double arrayParams[2] = {1, 2};
double (*params)[2] = &arrayParams;
alglib::autogkstate s;
double v;
alglib::autogkreport rep;
alglib::autogksmooth(0, 1, s);
alglib::autogkintegrate(s, Foo::Wrapper_To_Call_f, params);
alglib::autogkresults(s, v, rep);
std::cout << v << std::endl;
return 0;
}
I am trying pass the function as an argument, the Testabc is inherited from MainTest and the function I want to pass is protected function in MainTest class. I do not have the cpp access to the MainTest class which has this protected ReadTestPoint function.
Below is header file where I define the function that is taking the function as an argument.
#include <QObject>
#include <QDebug>
class TestManager
{
public:
TestManager();
~TestManager() {}
int ReadTestPointer(void *dp, unsigned int &val, int (*functioncall)(void *,
unsigned int&));
};
Below is the cpp for the TestManager
#include "testmanager.h"
#include<QDebug>
TestManager::TestManager(){}
int TestManager::ReadTestPointer(void* dp, unsigned int &num, int (*readt)
(void*, unsigned int&))
{
qDebug()<< "Function Pointer working";
int g;
g = (*readt)(dp, num);
return g;
}
The class from where I am making the call:
namespace PackageCore
{
TestAbc::TestAbc() : MainTest(){}
TestAbc::~TestAbc(){}
int TestAbc::Init()
{
// initialization code called once
m_config = reinterpret_cast<Test_BaseClass*>
(GetConfig(Test_BaseClass_INTERFACE_HASH));
return 0;
}
int TestAbc::DeInit()
{
return 0;
}
int TestAbc::Cycle()
{
TestManager m_TestManager;
unsigned int m_trigger;
int (*abc)(void *, unsigned int&) = ReadTestPoint(m_config-
>SHM_B_Trigger_U8, m_trigger);
m_TestManager.ReadTestPointer(m_config->SHM_B_Trigger_U8, m_trigger, abc);
qDebug()<< " getTrigger: " << m_trigger;
return 0;
}
}
But I get the compile time error on this:
C:\test_manager_git\testabc.cpp:39: error: invalid conversion from 'int' to 'int (*)(void*, unsigned int&)' [-fpermissive]
int (*abc)(void *, unsigned int&) = ReadTestPoint(m_config->SHM_B_Trigger_U8, m_trigger);
The MainTest.h is below:
class MainTest : public QObject
{
Q_OBJECT
public:
// Callbacks
virtual int Init() = 0;
virtual int Cycle() = 0;
virtual int DeInit() = 0;
protected:
int ReadTestPoint (void *dp, unsigned int &val);
};
Thanks
First of all, consider using things like std::function instead of rolling your own pointer nightmare. But lets get started...
Basically, in order to call a member function from pointer, you need the function pointer and a member instance. The following code is based on your question code with the added member pointer.
#include <iostream>
class MainTest
{
public:
protected:
int ReadTestPoint (void *dp, unsigned int &val)
{
std::cout << "protected ReadTestPoint called" << std::endl;
return 0;
}
};
class TestManager
{
public:
TestManager() {}
~TestManager() {}
int ReadTestPointer(void *dp, unsigned int &val, MainTest* instance, int (MainTest::*functioncall)(void *, unsigned int&))
{
return (instance->*functioncall)(dp, val);
}
};
class TestAbc : public MainTest
{
public:
void ExecTest()
{
TestManager testManager;
unsigned int tVal;
void* dummy = &tVal;
testManager.ReadTestPointer(dummy, tVal, this, &TestAbc::ReadTestPoint);
}
};
int main(void)
{
TestAbc test;
test.ExecTest();
return 0;
}
If you don't want to restrict yourself to a specific member type, consider using a template function:
class TestManager
{
public:
TestManager() {}
~TestManager() {}
template<typename Fn>
int ReadTestPointer(void *dp, unsigned int &val, Fn functioncall)
{
return functioncall(dp, val);
}
};
It will accept non-member functions and objects that overload the operator() with appropriate parameters and return types.
You can wrap the member function pointer in a Functor object:
template<typename TMember, typename TResult, typename TParam1, typename TParam2>
struct Functor
{
typedef TResult (TMember::*TFn)(TParam1, TParam2);
Functor(TMember* m, TFn func):member(m), fn(func){}
TMember* member;
TFn fn;
TResult operator()(TParam1 p1, TParam2 p2)
{
return (member->*fn)(p1, p2);
}
};
The following example includes a free function call and a member function call:
int FreeFn(void *dp, unsigned int &val)
{
std::cout << "free function called" << std::endl;
return 1;
}
class TestAbc : public MainTest
{
public:
void ExecTest()
{
TestManager testManager;
unsigned int tVal;
void* dummy = &tVal;
testManager.ReadTestPointer(dummy, tVal, Functor<TestAbc, int, void*, unsigned int&>(this, &TestAbc::ReadTestPoint));
testManager.ReadTestPointer(dummy, tVal, FreeFn);
}
};
consider the Utility class below:
It will contain lots of factory methods with same signature int function(int a, int b);
Utility.h
class Utility
{
public:
template<typename T, typename A, typename B>
static int get_function(T% function, int% number)
{
function = (T) add;
number = 10;
return 0;
}
static int add (int a, int b) {
return a+b;
}
};
this contains a template method (get_function()) to assign Function pointers from factory methods available in Utility class.
Main.cpp
typedef int (__stdcall *FP) (int a, int b);
ref class FPClass
{
public:
static FP fp;
static int number;
static void apply_function()
{
Utility::get_function<FP, int, int>(FPClass::fp, number);
cout << FPClass::fp(25, 45);
}
};
void main()
{
FPClass::apply_function();
}
What I want to achieve is, to assign the function pointer (FPClass::fp) by the template method (Utility:get_function).
But the function pointer parameter is not modified (always null) by the called function (Utility:get_function).
why is that?
Im bit new to c++, please let me describe my problem. I have a class called CSubcriber, which main purpose is to execute some callback function, of some type and some number of arguments. For example callbacks can be:
typedef void (*cb1)(void)
typedef int (*cb2)(int, int)
typedef char (*cb3)(int, int, void);
class itself is:
template <class CallbackType>
class CSubscriber {
public:
CSubscriber();
virtual ~CSubscriber();
CallbackType (*m_callback_newWay)(void *params);
void (*m_callback)(void *params);
int (*m_callback_int)(void *params);
void *m_cb_params;
int execute_cb();
void *m_params;
CSubscriber(void (*callback)(void *params), void *cb_params);
CSubscriber(int (*callback)(void *params), void *cb_params);
};
CSubscriber::CSubscriber(void (*callback)(void *params), void *cb_params){
m_callback = callback;
m_cb_params = cb_params;
}
CSubscriber::CSubscriber(int (*callback)(void *params), void *cb_params){
m_callback_int = callback;
m_cb_params = cb_params;
}
My main problem is now, how to write constructor, which will handle with all that variable arguments to callback. After constructing object in some particular moment, callback may be fired, for example:
typedef int (*callback)(void *params);
CSubscriber s(callback, params);
or
typedef void (*callback2)(void *params, int arr, char *ptr);
CSubscriber s(callback, params, arr, ptr);
Now, calling
s->m_callback()
I want to execute callback with all arguments which i passed for constructor.
I'd like to avoid writing ten different constructors, for each different number of arguments passed to callback function. Is it possible to do ?
Try something like this.
#include <iostream>
using namespace std;
typedef void (*cb1)(void);
typedef int (*cb2)(int, int);
typedef char (*cb3)(int, int, char);
template <class CallbackType>
class CSubscriber
{
public:
CSubscriber(): fcn1(0), fcn2(0), fcn3(0) {};
virtual ~CSubscriber(){};
CSubscriber(cb1 fcn): fcn1(fcn), fcn2(0), fcn3(0), a(), b() {};
CSubscriber(cb2 fcn, int p1, int p2): fcn1(0), fcn2(fcn), fcn3(0), a(p1), b(p2) {};
int execute_cb() {
if ( fcn1 != 0 ) {
(*fcn1)();
}
if ( fcn2 != 0 ) {
(*fcn2)(a,b);
}
};
protected:
cb1 fcn1;
cb2 fcn2;
cb3 fcn3;
int a, b;
};
void fcn1() {
cout << "in fcn1" << endl;
};
int fcn2(int a, int b) {
cout << "in fcn2, a " << a << ", b " << b << endl;
};
int main()
{
CSubscriber<int> cs;
CSubscriber<int> cs1(&fcn1);
CSubscriber<int> cs2(&fcn2, 1, 100);
cs.execute_cb();
cs1.execute_cb();
cs2.execute_cb();
}