Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You might try that solution (a little bit hacky, but I think, it should work for you):</p> <pre><code>void fortranFunction(int n, void udf(double*)) { double d = static_cast&lt;double&gt;(n); udf(&amp;d); } class myClass { public: void classUDF(double* a) { } }; #ifdef _MSC_VER #define THREADLOCALSTATIC __declspec(thread) static #define THREADLOCAL #else #define THREADLOCALSTATIC static ___thread #define THREADLOCAL ___thread #endif struct _trampolinebase { THREADLOCALSTATIC _trampolinebase* current_trampoline; }; THREADLOCAL _trampolinebase* _trampolinebase::current_trampoline = 0; #undef THREADLOCAL #undef THREADLOCALSTATIC template&lt;class CBRET, class CBARG1, class T&gt; struct _trampoline1 : _trampolinebase { typedef CBRET (T::*CALLBACKFN)(CBARG1); _trampoline1(T&amp; target, CALLBACKFN&amp; callback) : callback_(callback) , target_(target) { assert(current_trampoline == 0); current_trampoline = this; } static CBRET callback(CBARG1 a1) { _trampoline1* this_ = static_cast&lt;_trampoline1*&gt;(current_trampoline); current_trampoline = 0; return this_-&gt;trampoline(a1); } private: CBRET trampoline(CBARG1 a1) { return (target_.*callback_)(a1); } CALLBACKFN&amp; callback_; T&amp; target_; }; template&lt;class FRET, class FARG1, class CBRET, class CBARG1, class T, class F&gt; FRET call1_1(T&amp; target, CBRET (T::*callback)(CBARG1), F&amp; fortranfunction, FARG1 a) { typedef typename _trampoline1&lt;CBRET, CBARG1, T&gt; trampoline; trampoline t(target, callback); return fortranFunction(a, trampoline::callback); } int main() { int n=1; myClass myClassObj; call1_1&lt;void,int,void,double*&gt;(myClassObj, &amp;myClass::classUDF, fortranFunction, 1); } </code></pre> <p>With the 'threadlocal' stuff, this will work in multithreaded calls, too. You may omit that, if you don't use a multithreaded environment. It also works with recursive calls (e.g. if the callback calls another fortran function).</p> <p>This solution works only for one single argument plus callback for the fortran function and one single argument in the callback function itself, but you should be able to extend it easily. This is also, why I called it 'call1_1' (fortran function with 1 argument, callbackfunction with 1 argument). FRET is the return type of the fortran function, FARG1 the type of the first argument (int in this case). CBRET and CBARG are the same for the callback function.</p> <p>Before the fortran function is actually called, the target object is stored within a global (thread-local) variable. The fortran function calls a static callback function, which finally calls your member function.</p> <p>I invented the trampolinebase to instantiate the static member, I could also have used a global variable for that (but for some reason, I don't like global variables too much) ;-)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload