Calling GSL function inside a class in a shared library - c++

I'm trying make a shared library in c++ implementing tools for Fermi gases. I'm using the GSL library to solve a function numerically and my code runs without a problem without when running as a script, but when trying to convert it to a shared library and classes I encounter problems.
I've seen similar questions:
Q1
Q2
Q3
I'm fairly new to c++-programming and cannot seem to adapt the different answers to my problem. Probably since I do not quite understand the answers.
My code is:
/* Define structure for the GSL-function: chempot_integrand */
struct chempot_integrand_params { double mu; double T; };
double
ChemicalPotential::chempot_integrand (double x, void * params){
/* Computes the integrand for the integral used to obtain the chemical potential.
*
* This is a GSL-function, which are integrated using gsl_integration_qag.
*/
// Get input parameters.
struct chempot_integrand_params * p = (struct chempot_integrand_params *) params;
double mu = p->mu;
double T = p->T;
// Initiate output parameters for GSL-function.
gsl_sf_result_e10 result;
int status = gsl_sf_exp_e10_e( ( gsl_pow_2(x) - mu ) / T , &result );
if (status != GSL_SUCCESS){
printf ("Fault in calculating exponential function.");
}
// Return (double) integrand.
return (gsl_pow_2(x) / ( 1 + result.val * gsl_sf_pow_int(10,result.e10) ));
}
/* Define structure for the GSL-function: chempot_integration */
struct chempot_integral_params { double T; };
double
ChemicalPotential::chempot_integration (double mu, double T){
/* Computes the integral used to obtain the chemical potential using the integrand: chempot_integrand.
*/
// Set input parameters for the integrand: chempot_integrand.
struct chempot_integrand_params params_integrand = { mu, T };
// Initiate the numerical integration.
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000); // Allocate memory for the numerical integration. Can be made larger if neccessary, REMEMBER to change it in the function call: gsl_integration_qag as well.
double result, error;
gsl_function F;
F.function = &ChemicalPotential::chempot_integrand;
F.params = &params_integrand;
// Upper limit for integration
double TOL = 1e-9;
double upp_lim = - T * gsl_sf_log(TOL) + 10;
gsl_integration_qag (&F, 0, upp_lim, 1e-12, 1e-12, 1000, 6, w, &result, &error);
// Free memory used for the integration.
gsl_integration_workspace_free (w);
return result;
}
and when compiling I get the error
error: cannot convert ‘double (Fermi_Gas::ChemicalPotential::*)(double, void*)’ to ‘double (*)(double, void*)’
in line
F.function = &ChemicalPotential::chempot_integrand;

It is indeed interesting that people ask this over and over again. One reason may be that the proposed solutions are not easy to understand. I for one had problems understanding and implementing them. (the solutions did not work out of the box for me, as you might expect.)
With the help of tlamadon I just figured out a solution that may be helpful here as well. Let's see what you guys think.
So just to recap, the problem is that you have a class that contains a member function on which you want to operate with something from the GSL library. Our example is useful if the GSL interface requires a
gsl_function F;
see here for a definition.
So here is the example class:
class MyClass {
private:
gsl_f_pars *p; // not necessary to have as member
public:
double obj(double x, void * pars); // objective fun
double GetSolution( void );
void setPars( gsl_f_pars * xp ) { p = xp; };
double getC( void ) ; // helper fun
};
The objective of this exercise is to be able to
initiate MyClass test,
supply it with a paramter struct (or write a corresponding constructor), and
call test.GetSolution() on it, which should return whatever the GSL function was used for (the minimum of obj, a root, the integral or whatever)
The trick is now to put have an element in the parameter struct gsl_f_pars which is a pointer to MyClass. Here's the struct:
struct gsl_f_pars {
double a;
double b;
double c;
MyClass * pt_MyClass;
};
The final piece is to provide a wrapper that will be called inside MyClass::GetSolution() (the wrapper is a stand in for the member function MyClass::obj, which we cannot just point to with &obj inside the class). This wrapper will take the parameter struct, dereference pt_MyClass and evaluate pt_MyClass's member obj:
// Wrapper that points to member function
// Trick: MyClass is an element of the gsl_f_pars struct
// so we can tease the value of the objective function out
// of there.
double gslClassWrapper(double x, void * pp) {
gsl_f_pars *p = (gsl_f_pars *)pp;
return p->pt_MyClass->obj(x,p);
}
The full example is a bit too long to post here, so I put up a gist. It's a header file and a cpp file, it should be working wherever you have GSL. Compile and run with
g++ MyClass.cpp -lgsl -o test
./test

This is a duplicate question. See Q1 or Q2 for example. Your problem is the following: you cannot convert pointers to member functions to free function pointers. To solve your problem, there are two options. You can define your member function as static (which is bad in 90% of the case because the member function will not be attached to any instantiation of your class and that is why you can convert it to a free function) or you can use the wrapper you linked that will use a static member functions under the hood to make your code compatible with gsl without the need of declaring your particular member function static.
EDIT #Florian Oswald. Basically your entire solution can be implemented in 2 lines using std::bind the wrapper I cited before
gsl_function_pp Fp( std::bind(&Class::member_function, &(*this), std::placeholders::_1) );
gsl_function *F = static_cast<gsl_function*>(&Fp);
In practice is this is just 1 extra line from a pure C code!
As I stated in a comment, wrapping every member function that you want to integrate using an extra global struct and an extra global function is cumbersome and pollute your code with a lot of extra functions/struct that are completely unnecessary. Why use c++ if we refuse to use the features that make C++ powerful and useful (in comparison to C)?
Another classical Example: if you want to pass a LOT of parameters, use lambda functions (no extra struct or global functions) !!!
To be more precise: Imagine you have 2 parameters (doubles) .
//Declare them (locally) here
double a1 = ...;
double a2 = ...;
// Declare a lambda function that capture all of them by value or reference
// no need to write another struct with these 2 parameters + class pointer
auto ptr = [&](double x)->double {/.../};
// Cast to GSL in 3 lines using the wrapper
std::function<double(double)> F1(ptr);
gsl_function_pp F2(F1);
gsl_function *F = static_cast<gsl_function*>(&F2);
No extra global struct of global functions and no extra wrapper (the same wrapper that solved the problem of integrating member function also solved the problem of integrating a lambda expression). Of course this is a matter of style in the end, but in the absence of these nice features that allow the use of C libraries without code bloat, I would never leave C.

Related

no viable conversion from 'lambda' to 'void ...'

I need to give a function another function or lambda as a parameter, and this works, more or less.
There is an error as soon as I try to define a capture for a lambda in c++14. You can see the sample code here:
// this is part of a library (I cannot change it)
class SVGElement {
//...
public:
void onclick(void (*handler)(SVGElement *)) {
handler(this);
}
void rotateBy(int angle) {/*...*/}
//...
};
// my code
SVGElement mySvgElement = SVGElement();
// this works
mySvgElement.onclick([](SVGElement* clicked){clicked->rotateBy(15);});
// as soon as I define a capture, there is an error
int angle = 15;
mySvgElement.onclick([angle](SVGElement* clicked){clicked->rotateBy(angle);});
As you can see, part of the problem is that I cannot change part of the code. Is there anything I can do or am I missing something or is the situation hopeless?
Here is the error I get:
input_line_7:22:22: error: no viable conversion from '(lambda at input_line_7:22:22)' to 'void (*)(__cling_N52::SVGElement *)'
mySvgElement.onclick([angle](SVGElement* clicked){clicked->rotateBy(angle);});
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
input_line_7:7:25: note: passing argument to parameter 'handler' here
void onclick(void (*handler)(SVGElement *)) {
^
Functions can't have captures. Lambdas can, which means they aren't functions. A lambda with no captures can be converted to a function pointer but a lambda with captures cannot.
This code:
int angle = 15;
mySvgElement.onclick([angle](SVGElement* clicked){clicked->rotateBy(angle);});
is effectively equivalent to:
int angle = 15;
struct MyLambda {
int angle;
void operator()(SVGElement* clicked){clicked->rotateBy(angle);}
};
mySvgElement.onclick(MyLambda{angle});
and there is no way to treat a MyLambda object as a function pointer, because it's not a function, it's actually an object with variables in it.
If the lambda had no captures, you could easily construct a wrapper function like this:
void MyLambda_wrapper(SVGElement* clicked) {
MyLambda l;
l(clicked);
}
and then you could do
mySvgElement.onclick(MyLambda_wrapper);
which is effectively what the compiler does. However, this doesn't work with captures, because the wrapper function needs to know what values to put in the captures.
Lambdas don't let you do anything new with the language that you couldn't do before. They are just a shortcut to do things you could already do.
You do have some options to store the angle, though:
If the angle is always 15, you can just hardcode 15.
If the angle is the same for all shapes, you can make it a global variable.
Often, libraries will leave some member in their data structures for the application to use, often called void *context or void *userdata. You could store the angle in that variable:
int angle = 15;
mySvgElement.userdata = (void*)angle;
mySvgElement.onclick([](SVGElement* clicked){clicked->rotateBy((int)clicked->userdata);});
If you have more than one of these, you'd need to store a struct pointer and remember to free it when the element is destroyed:
mySvgElement.userdata = new my_svg_element_data;
((my_svg_element_data*)mySvgElement.userdata)->left_click_angle = 15;
((my_svg_element_data*)mySvgElement.userdata)->right_click_angle = 30;
mySvgElement.onclick([](SVGElement* clicked){clicked->rotateBy(((my_svg_element_data*)clicked->userdata)->left_click_angle);});
mySvgElement.onrclick([](SVGElement* clicked){clicked->rotateBy(((my_svg_element_data*)clicked->userdata)->right_click_angle);});
mySvgElement.ondestroy([](SVGElement* destroyed){delete (my_svg_element_data*)destroyed->userdata;});
You could store the angle in your own global std::unordered_map<SVGElement*, int> click_angle;:
click_angle[&mySvgElement] = 15;
mySvgElement.onclick([](SVGElement* clicked){clicked->rotateBy(click_angle[clicked]);});
mySvgElement.ondestroy([](SVGElement* destroyed){click_angle.erase(destroyed);});

is there a way to store a generic templated function pointer?

The Goal:
decide during runtime which templated function to use and then use it later without needing the type information.
A Partial Solution:
for functions where the parameter itself is not templated we can do:
int (*func_ptr)(void*) = &my_templated_func<type_a,type_b>;
this line of code can be modified for use in an if statement with different types for type_a and type_b thus giving us a templated function whose types are determined during runtime:
int (*func_ptr)(void*) = NULL;
if (/* case 1*/)
func_ptr = &my_templated_func<int, float>;
else
func_ptr = &my_templated_func<float, float>;
The Remaining Problem:
How do I do this when the parameter is a templated pointer?
for example, this is something along the lines of what I would like to do:
int (*func_ptr)(templated_struct<type_a,type_b>*); // This won't work cause I don't know type_a or type_b yet
if (/* case 1 */) {
func_ptr = &my_templated_func<int,float>;
arg = calloc(sizeof(templated_struct<int,float>, 1);
}
else {
func_ptr = &my_templated_func<float,float>;
arg = calloc(sizeof(templated_struct<float,float>, 1);
}
func_ptr(arg);
except I would like type_a, and type_b to be determined during runtime. I see to parts to the problem.
What is the function pointers type?
How do I call this function?
I think I have the answer for (2): simply cast the parameter to void* and the template function should do an implicit cast using the function definition (lease correct me if this won't work as I think it will).
(1) is where I am getting stuck since the function pointer must include the parameter types. This is different from the partial solution because for the function pointer definition we were able to "ignore" the template aspect of the function since all we really need is the address of the function.
Alternatively there might be a much better way to accomplish my goal and if so I am all ears.
Thanks to the answer by #Jeffrey I was able to come up with this short example of what I am trying to accomplish:
template <typename A, typename B>
struct args_st {
A argA;
B argB;
}
template<typename A, typename B>
void f(struct args_st<A,B> *args) {}
template<typename A, typename B>
void g(struct args_st<A,B> *args) {}
int someFunction() {
void *args;
// someType needs to know that an args_st struct is going to be passed
// in but doesn't need to know the type of A or B those are compiled
// into the function and with this code, A and B are guaranteed to match
// between the function and argument.
someType func_ptr;
if (/* some runtime condition */) {
args = calloc(sizeof(struct args_st<int,float>), 1);
f((struct args_st<int,float> *) args); // this works
func_ptr = &g<int,float>; // func_ptr should know that it takes an argument of struct args_st<int,float>
}
else {
args = calloc(sizeof(struct args_st<float,float>), 1);
f((struct args_st<float,float> *) args); // this also works
func_ptr = &g<float,float>; // func_ptr should know that it takes an argument of struct args_st<float,float>
}
/* other code that does stuff with args */
// note that I could do another if statement here to decide which
// version of g to use (like I did for f) I am just trying to figure out
// a way to avoid that because the if statement could have a lot of
// different cases similarly I would like to be able to just write one
// line of code that calls f because that could eliminate many lines of
// (sort of) duplicate code
func_ptr(args);
return 0; // Arbitrary value
}
Can't you use a std::function, and use lambdas to capture everything you need? It doesn't appear that your functions take parameters, so this would work.
ie
std::function<void()> callIt;
if(/*case 1*/)
{
callIt = [](){ myTemplatedFunction<int, int>(); }
}
else
{
callIt = []() {myTemplatedFunction<float, float>(); }
}
callIt();
If I understand correctly, What you want to do boils down to:
template<typename T>
void f(T)
{
}
int somewhere()
{
someType func_ptr;
int arg = 0;
if (/* something known at runtime */)
{
func_ptr = &f<float>;
}
else
{
func_ptr = &f<int>;
}
func_ptr(arg);
}
You cannot do that in C++. C++ is statically typed, the template types are all resolved at compile time. If a construct allowed you to do this, the compiler could not know which templates must be instanciated with which types.
The alternatives are:
inheritance for runtime polymorphism
C-style void* everywhere if you want to deal yourself with the underlying types
Edit:
Reading the edited question:
func_ptr should know that it takes an argument of struct args_st<float,float>
func_ptr should know that it takes an argument of struct args_st<int,float>
Those are incompatible. The way this is done in C++ is by typing func_ptr accordingly to the types it takes. It cannot be both/all/any.
If there existed a type for func_ptr so that it could take arguments of arbitrary types, then you could pass it around between functions and compilation units and your language would suddenly not be statically typed. You'd end up with Python ;-p
Maybe you want something like this:
#include <iostream>
template <typename T>
void foo(const T& t) {
std::cout << "foo";
}
template <typename T>
void bar(const T& t) {
std::cout << "bar";
}
template <typename T>
using f_ptr = void (*)(const T&);
int main() {
f_ptr<int> a = &bar<int>;
f_ptr<double> b = &foo<double>;
a(1);
b(4.2);
}
Functions taking different parameters are of different type, hence you cannot have a f_ptr<int> point to bar<double>. Otherwise, functions you get from instantiating a function template can be stored in function pointers just like other functions, eg you can have a f_ptr<int> holding either &foo<int> or &bar<int>.
Disclaimer: I have already provided an answer that directly addresses the question. In this answer, I would like to side-step the question and render it moot.
As a rule of thumb, the following code structure is an inferior design in most procedural languages (not just C++).
if ( conditionA ) {
// Do task 1A
}
else {
// Do task 1B
}
// Do common tasks
if ( conditionA ) {
// Do task 2A
}
else {
// Do task 2B
}
You seem to have recognized the drawbacks in this design, as you are trying to eliminate the need for a second if-else in someFunction(). However, your solution is not as clean as it could be.
It is usually better (for code readability and maintainability) to move the common tasks to a separate function, rather than trying to do everything in one function. This gives a code structure more like the following, where the common tasks have been moved to the function foo().
if ( conditionA ) {
// Do task 1A
foo( /* arguments might be needed */ );
// Do task 2A
}
else {
// Do task 1B
foo( /* arguments might be needed */ );
// Do task 2B
}
As a demonstration of the utility of this rule of thumb, let's apply it to someFunction(). ... and eliminate the need for dynamic memory allocation ... and a bit of cleanup ... unfortunately, addressing that nasty void* is out-of-scope ... I'll leave it up to the reader to evaluate the end result. The one feature I will point out is that there is no longer a reason to consider storing a "generic templated function pointer", rendering the asked question moot.
// Ideally, the parameter's type would not be `void*`.
// I leave that for a future refinement.
void foo(void * args) {
/* other code that does stuff with args */
}
int someFunction(bool condition) {
if (/* some runtime condition */) {
args_st<int,float> args;
foo(&args);
f(&args); // Next step: pass by reference instead of passing a pointer
}
else {
args_st<float,float> args;
foo(&args);
f(&args); // Next step: pass by reference instead of passing a pointer
}
return 0;
}
Your choice of manual memory management and over-use of the keyword struct suggests you come from a C background and have not yet really converted to C++ programming. As a result, there are many areas for improvement, and you might find that your current approach should be tossed. However, that is a future step. There is a learning process involved, and incremental improvements to your current code is one way to get there.
First, I'd like to get rid of the C-style memory management. Most of the time, using calloc in C++ code is wrong. Let's replace the raw pointer with a smart pointer. A shared_ptr looks like it will help the process along.
// Instead of a raw pointer to void, use a smart pointer to void.
std::shared_ptr<void> args;
// Use C++ memory management, not calloc.
args = std::make_shared<args_st<int,float>>();
// or
args = std::make_shared<args_st<float,float>>();
This is still not great, as it still uses a pointer to void, which is rarely needed in C++ code unless interfacing with a library written in C. It is, though, an improvement. One side effect of using a pointer to void is the need for casts to get back to the original type. This should be avoided. I can address this in your code by defining correctly-typed variables inside the if statement. The args variable will still be used to hold your pointer once the correctly-typed variables go out of scope.
More improvements along this vein can come later.
The key improvement I would make is to use the functional std::function instead of a function pointer. A std::function is a generalization of a function pointer, able to do more albeit with more overhead. The overhead is warranted here in the interest of robust code.
An advantage of std::function is that the parameter to g() does not need to be known by the code that invokes the std::function. The old style of doing this was std::bind, but lambdas provide a more readable approach. Not only do you not have to worry about the type of args when it comes time to call your function, you don't even need to worry about args.
int someFunction() {
// Use a smart pointer so you do not have to worry about releasing the memory.
std::shared_ptr<void> args;
// Use a functional as a more convenient alternative to a function pointer.
// Note the lack of parameters (nothing inside the parentheses).
std::function<void()> func;
if ( /* some runtime condition */ ) {
// Start with a pointer to something other than void.
auto real_args = std::make_shared<args_st<int,float>>();
// An immediate function call:
f(real_args.get());
// Choosing a function to be called later:
// Note that this captures a pointer to the data, not a copy of the data.
// Hence changes to the data will be reflected when this is invoked.
func = [real_args]() { g(real_args.get()); };
// It's only here, as real_args is about to go out of scope, where
// we lose the type information.
args = real_args;
}
else {
// Similar to the above, so I'll reduce the commentary.
auto real_args = std::make_shared<args_st<float,float>>();
func = [real_args]() { g(real_args.get()); };
args = real_args;
}
/* other code that does stuff with args */
/* This code is probably poor C++ style, but that can be addressed later. */
// Invoke the function.
func();
return 0;
}
Your next step probably should be to do some reading on these features so you understand what this code does. Then you should be in a better position to leverage the power of C++.

Using a boost::numeric::odeint stepper inside a complicated class

I have an extremely convoluted system of numerical rate equations, which are to be solved by the class ElectronSolver. The electron state is handled by a separate class state_type, not shown here.
A simplified template of the problem class appears as
ElectronSolver.h
class ElectronSolver {
public:
ElectronSolver(const char* filename, ofstream& log);
void solve();
void print(const std::string& fname);
std::vector<double> T; // Times, in fs
std::vector<state_type> Y; // stores the state_t's
private:
// steps, State, value, Derivative, Time, Algebra
adams_bashforth_moulton< 5, state_type, double, state_type, double, vector_space_algebra > abm;
void set_initial_conditions();
// Model parameters
PhotonFlux pf;
void sys(const state_type& s, state_type& sdot, const double t);
};
ElectronSolver.cpp
void ElectronSolver::set_initial_conditions(){
// Set the initial T such that pulse peak occurs at T=0
T[0] = -timespan/2;
Y[0] = state_type(Store, num_elec_points);
abm.initialize( sys, Y[0], T[0], dt ); // This line produces an error
}
void ElectronSolver::sys(const state_type& s, state_type& sdot, const double t){
// complicated system modifying sdot
sdot.flux += pf(t)*s.flux;
}
However, some research revealed why the marked line throws a compile error.
As far as I can understand sys as declared here must be called "on a class", so cannot simply be passed as a reference. This question got around that by declaring sys as static, but that won't work here since I'm relying on calling other members of ElectronSolver in sys.
There is little concievable reason that I would need multiple instances of ElectronSolver, but I would like to leave the option there in case any code maintainers want to have two different electron models.
As far as I can tell, I have four options:
make everything sys needs static (less than desirable due to ElectronSolver inheriting from other classes, but doable)
Construct some kind of a wrapper for the sys function (possibly has a performance hit, and more to the point, I don't know how to do this)
Implement the ODE stepper myself to avoid the headaches of using boost.
????
Which solution strikes the best bargain between
- Performance (though the largest performance bottleneck is probably the time it takes sys to execute)
- Code elegance
- Modularity
?
Whether or not you want to continue using boost is a decision only you can make, but it's easy to create a wrapper with no performance hit.
You'll want to wrap sys in a lambda that captures this. This should not have a performance hit, as the lambda will be inlined when optimizations are turned on.
You would call it like this:
abm.initialize(
[this](const state_type& s, state_type& sdot, const double t) {
this->sys(s, sdot, t);
},
Y[0],
T[0],
dt
);
The lambda is basically an implicit wrapper struct that holds a reference to this and defines an operator()(const state_type& s, state_type& sdot, const double t).
I created an example in godbolt that shows this, simplifying and filling in your code where necessary for the example. If you change the optimization between -O0 and -O3 you can see the lambda code is stripped away and the inner method is fully inlined.
Another option is use std::bind to create a bare function out of the member function:
abm.initialize(
std::bind(&ElectronSolver::sys, std::ref(*this), _1, _2, _3),
Y[0],
T[0],
dt
);
along with this elsewhere:
#include <functional>
using namespace std::placeholders;
to get all the symbols into scope. std::bind creates a new function where the some arguments are already filled in. In this case the implicit first argument, the object itself, is filled in with a reference to this. The rest of the arguments are given special placeholders to indicate the new function will fill them in with its arguments. The std::ref, forces taking this by reference rather than by copy. This method will also have zero overhead.

Is this C callback safe with C++ objects?

My purpose is to call some C function from my C++ code and pass some C++ objects.
In fact I am using a integration routine from the GSL libray(written in C), see this link,
My code snippet:
// main.cpp
#include <stdio.h>
#include <gsl/gsl_integration.h>
#include <myclass.h>
/* my test function. */
double testfunction ( double x , void *param ) {
myclass *bar=static_cast<myclass*>(param);
/*** do something with x and bar***/
return val;
}
int main ( int argc , char *argv[] ) {
gsl_function F; // defined in GSL: double (* function) (double x, void * params)
/* initialize.*/
gsl_integration_cquad_workspace *ws =
gsl_integration_cquad_workspace_alloc( 200 ) ;
/* Prepare test function. */
myclass foo{}; // call myclass constructor
F.function = &testfunction;
F.params = &foo;
/* Call the routine. */
gsl_integration_cquad( &F, 0.0,1.0,1.0e-10,1.0e-10,ws, &res,&abserr,&neval);
/* Free the workspace. */
gsl_integration_cquad_workspace_free( ws );
return 0;
}
In my case, direct calling gsl_integration_cquad seems OK, provided the header includes sth like "ifdef __cplusplus", my concern is about the callback F,originally defined in C, am I allowed to pass the testfunction and also the C++ foo object in this way ? .
or is there any better way to do this kind of stuff, maybe overloading and use a functor?
P.S. Am I allowed to do exeption handling within the callback function? (use try catch inside "testfunction"). It works in my case but not sure if it's legal.
I'm not familiar with the library in question, but in general,
when passing a pointer to a callback and a void* to
a C routine, which will call the callback back with the void*,
there are two things you need to do to make it safe:
The function whose address you pass must be declared extern "C".
You'll get away with not doing this with a lot of compilers, but
it isn't legal, and a good compiler will complain.
The type you convert to the void* must be exactly the same
type as the type you cast it back to in the callback. The
classic error is to pass something like new Derived to the
C function, and cast it back to Base* in the callback. The
round trip Derived*→void*→Base* is undefined
behavior. It will work some of the time, but at other times, it
may crash, or cause any number of other problems.
And as cdhowie pointed out in a comment, you don't want to
allow exceptions to propagate accross the C code. Again, it
might work. But it might not.
For the exact example you posted, the only thing you need to do
is to declare testfunction as extern "C", and you're all
right. If you later start working with polymorphic objects,
however, beware of the second point.
You can use
myclass *bar=static_cast<myclass*>(param);
with void*.
If you meant something like transporting a c++ class pointer through a c callback's void* pointer, yes it's safe to do a static_cast<>.
There's no kind of losing c++ specific attributes of this class pointer, when passed through c code. Though passing a derived class pointer, and static casting back to the base class, won't work properly as #James Kanze pointed out.
The void* will likely just be passed trough by the C library without looking at the pointed-to data, so it's not a problem if this contains a C++ class. As log as you cast the void* to the correctly there shouldn't be any problems.
To make sure the callback function itself is compatible, you can declare it as extern "C". Additionally you should make sure that no exceptions are thrown from the callback function, since the C code calling the callback won't expect those.
All together I would split up the code into one function that does the real work and another function that is used as the callback and handles the interface with the C library, for example like this:
#include <math.h>
double testfunction ( double x ,myclass *param ) {
/*** do something with x and bar***/
return val;
}
extern "C" double testfunction_callback ( double x , void *param ) {
try {
myclass *bar=reinterpret_cast<myclass*>(param);
return testfunction(x, bar);
}
catch(...) {
std::cerr << "Noooo..." << std::endl;
return NAN;
}
}

Using gsl_function using a supplied R function

I am currently attempting to use the gsl_function from GSL library through RcppGSL using a .cpp file and calling it using sourceCpp(). The idea is to perform numerical integration with gsl_integration_qags, also from GSL. My C code invokes a user defined R function (SomeRFunction in my code below) saved into the global environment. The code is:
#include <RcppGSL.h>
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_vector.h>
// [[Rcpp::depends(RcppGSL)]]
// [[Rcpp::export]]
double integfn1(double ub, double lb, double abserr, double Rsq, int pA){
double result, abserror;
Rcpp::Environment global = Rcpp::Environment::global_env();
Rcpp::Function f1 = global["SomeRFunction"];
struct my_f_params { double Rsq; int pA; };
struct my_f_params params = { Rsq, pA };
gsl_function F;
F.function = & f1;
F.params = &params;
double lb1 = lb;
double ub1 = ub;
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);
gsl_integration_qags (&F, lb1, ub1, 1e-8, 1e-8, 1000, w, &result, &abserror);
printf ("result = % .18f\n", result);
printf ("estimated error = % .18f\n", abserror);
gsl_integration_workspace_free (w);
return result;
}
And the following error comes up:
"cannot convert 'Rcpp::Function* {aka Rcpp::Function_Impl<Rcpp::PreserveStorage>*}' to 'double (*)(double, void*)' "
The problem is in the line where I declare what the function to integrate is (i.e. "F.function = & f1;").
I looked up similar problems but couldn't find anything listed... Any hint will be greatly appreciated!
Many thanks
I created a working example (and timed it against C) in which you can pass an arbitrary user-defined R function to the GSL function QAWF. You should be able to generalize it to other gsl functions as well.
See the example here: https://sites.google.com/site/andrassali/computing/user-supplied-functions-in-rcppgsl
As noted above, the competing C implementation is much-much faster.
Quick comments:
You write: My C code invokes a user defined R function (SomeRFunction in my code below) saved into the global environment. So your C code will still slow down a lot at each function evaluation due to the cost of calling R, and the slower speed of R.
My RcppDE package (which is also for optmisation) as as example of using external pointers (Rcpp::XPtr) to pass a user-defined C function down to the optimiser. Same flexibility. better speed.
Your compile error is exactly at that intersection---you can't "just pass" an Rcpp object to a void pointer. Rcpp::XPtr helps you there, but you too need to know what you are doing so a the working example may be helpful.
This is really an Rcpp question but you didn't add the tag, so I just did.
F.function expects a function of this signature double (*) (double x, void * params) so a function taking a double then a void*. You need to help Rcpp::Function if you want this to fly.
This is typical C apis stripping away types. So what you need to give as function is something that understand what you have as params and is able to call the R function, with the right parameters and convert to a double. The simple way to do this is to consider the R function as data, so augment the struct to make it something like this:
struct my_f_params { double Rsq; int pA; Function& rfun };
This way, the function you pass as function can be something like this:
double proxy_fun( double x, void* params ){
my_f_params* data = reinterpret_cast<my_f_params*>(params) ;
return as<double>( data->rfun(x, data->Rsq, data->pA ) ) ;
} ;
So you can build your gsl_function something like this:
my_f_params params = { Rsq, pA, f1 };
gsl_function F ;
F.function = &proxy_fun ;
F.params = &params;
With a bit of C++11 variadic templates and tuples, you could generalize this to anything instead of the (double, int) pair but it is more work.