octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Avoid global pointers in dae


From: Carlo De Falco
Subject: Re: Avoid global pointers in dae
Date: Mon, 15 Aug 2016 08:28:35 +0000

On 15 Aug 2016, at 09:09, Francesco Faccio <address@hidden> wrote:

> 
> Carlo de Falco<address@hidden> wrote:
> >On 14 Aug 2016, at 02:11, Carlo de Falco <address@hidden> wrote:
> >
> >> 
> >> On 14 Aug 2016, at 01:17, Carnë Draug <address@hidden> wrote:
> >> 
> >>> On 13 August 2016 at 06:30, Francesco Faccio
> >>> <address@hidden> wrote: 
> >>>> [...]
> >>>> Since I don't own copiright, I would like to know if it's ok to change 
> >>>> the
> >>>> interface of that base class. 
> >>>> 
> >>> 
> >>> The ability to change the code is one of the main points behind GPL.
> >>> So yes, you can change the source.
> >>> 
> >>> Just beware that if the interface is public you should try to keep
> >>> backwards compatibility.  I grepped all of the Octave Forge for DAEFunc
> >>> and all of its subclasses [1] but couldn't find it being used so you
> >>> should be fine.
> >>> 
> >>> Carnë
> >>> 
> >>> [1] http://octave.org/doxygen/4.1/d9/d83/classDAEFunc.html
> >> 
> >> Francesco,
> >> 
> >> As Carnë's answer shows, your question is ill posed and leads to 
> >> misunderstandings:
> >> 
> >> of course you can change the source, the GPL license grants you this right,
> >> the real question would be whether that change would be accepted by Octave
> >> developers in the main repository or not.
> >
> >To make this more clear, who holds copyright is pointless and referring to 
> >that
> >in your question is distracting.
> >
> >The question is a technical question about the class design and 
> >functionality, not 
> >a legal question about licenses and copyright.
> >
> >> c.
> 
> Carlo, Carnë,
> 
> sorry, my question was not well posed and thank you for making this clear to 
> me. 
> I'm not still sure we can avoid global pointers wrt the design of Octave. Let 
> me explain why:
> 
> In my dld-function I have a pointer to the octave_function provided by the 
> user and I use it inside a  DAERHSFunc to compute residual. I use a pointer 
> to thisDAERHSFunc when I construct an object of my class.
> 
> Inside my class I have methods which allows me to interface with Sundials' 
> types and functions. In particular, I use a lambda to pass a residual 
> function (with fixed signature) to a function of Sundials (with fixed 
> signature). 
> 
> The problem here is that I cannot use classes and methods of libinterp inside 
> liboctave to compute residual, I can only put a forward declaration in my 
> class.
> 
> My first and actual solution is to call inside my lambda a pointer (stored in 
> the base class) to the DAERHSFunc defined in my dld-fun, so I can call 
> methods of class octave_function and I avoid code duplication, but I need to 
> declare the poiner to octave_function global in my dld-function.
> 
> What I was trying to do, was to store the octave_function pointer as member 
> of my class and to pass it as a parameter when I dereference the pointer  to 
> the DAERHSFunc  in my lambda.  But since it has incomplete type I get 
> segmentation fault. 
> 
> I think I could avoid global pointers changing completely the constructor of 
> my class, but then inheriting from DAE would be meaningless.
> 
> Do you have any suggestions or do you know some workaround to this?
> 
> Thank you,
> 
> Francesco


Hi Francesco,

As a general 

Can you provide links to lines in your code on bitbucket so we can follow more 
clearly what you are talking about?

Some more specific questions:

Are lambdas among the C++11 features that are acceptable to use in Octave 4.1?
Why is your class IDA inheriting from DAE? What methods from the base class are 
you actually using?

The most straightforward method I see for encapsulating a C callback function 
inside a C++ class
is the following:

1 - include a "static" member function in your class with the signature 
required by the C callback

 static int 
 IDA::res_interface (realtype tt, N_Vector yy, N_Vector yp, N_Vector rr, void 
*user_data);

2 - use the void pointer user_data to pass the 'this' pointer of the current 
object 
    
 static int 
 IDA::res_interface (realtype tt, N_Vector yy, N_Vector yp, N_Vector rr, void 
*user_data)
 {
   IDA *self = static_cast<IDA*>(user_data);
   ...
 } 

3 - you can now access the non static class member methods via the pointer

 static int 
 IDA::res_interface (realtype tt, N_Vector yy, N_Vector yp, N_Vector rr, void 
*user_data)
 {
   ...
   self -> res_implementation (realtype tt, N_Vector yy, N_Vector yp, N_Vector 
rr)
 } 

The reason for using this pattern is that you cannot form a C function pointer 
to 
a non static class member method, while you can pass a pointer to the static 
member 
method IDA::res_interface.

How does your design differ from this approach?
c.
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]