I have a struct as follows:
struct power_model {
int64_t (*estimate_energy)(statistics *stats, statistics *scaled_stats, parameters *from, parameters *to, energy_container *energy_container);
int64_t (*estimate_performance)(statistics *stats, parameters *params);
uint32_t (*freq_to_volt)(uint32_t freq);
};
There are multiple power models that my code contains. I would like to wrap these models with SWIG and expose them to Python so that I can run my unit tests.
While the SWIG documentation talks about exposing function pointers, it does not talk about function pointers contained within structs. I tried to encapsulate the calls in my interface file
%{
#include "models.h"
%}
%include "models.h"
%extend power_model {
%pythoncallback;
int64_t (*estimate_energy)(statistics *stats, statistics *scaled_stats, parameters *from, parameters *to, energy_container *energy_container);
int64_t (*estimate_performance)(statistics *stats, parameters *params);
uint32_t (*freq_to_volt)(uint32_t freq);
%nopythoncallback;
}
I also tried prefixing the field names with %constant.
With these approaches, I always end up with the same error:
In [3]: model.estimate_energy()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-b2e3ace2fc9b> in <module>()
----> 1 model.estimate_energy()
TypeError: 'SwigPyObject' object is not callable
How can I call the underlying functions referenced by the function pointers contained within struct power_model?
Edit:
To elaborate on my setup, I am also sources of two additional files to better explain the setup I'm trying to achieve with the power_model interface.
nexus5.c
static int64_t estimate_energy(statistics *stats, statistics *scaled_stats, parameters *from, parameters *to, energy_container *energy) {
...
}
static int64_t estimate_performance(statistics *stats, parameters *params) {
...
}
static uint32_t freq_to_volt(uint32_t freq) {
...
}
struct power_model nexus5_power_model = {
.estimate_energy = estimate_energy,
.estimate_performance = estimate_performance,
.freq_to_volt = freq_to_volt,
};
galaxy_s.c
static int64_t estimate_energy(statistics *stats, statistics *scaled_stats, parameters *from, parameters *to, energy_container *energy) {
...
}
static int64_t estimate_performance(statistics *stats, parameters *params) {
...
}
static uint32_t freq_to_volt(uint32_t freq) {
...
}
struct power_model galaxy_s_power_model = {
.estimate_energy = estimate_energy,
.estimate_performance = estimate_performance,
.freq_to_volt = freq_to_volt,
};
typedef struct A { fptr_t f;} A;and store and execute functions. No problemstatic int64_t estimate_energy(...). How would I include these functions in my interface file and wrap them around%pythoncallback;. For me, the whole point of using struct with function pointers is to provide an interface that different models can implement in differing ways.models.hthat contains thestruct power_model. The actual implementation of all of these function pointers are all static functions which I cannot prototype in header files or in the interface file. Even if I could prototype them in the interface file, they all have the same name - something I can easily change..but that makes me question whether this is the right approach