[Gambas-devel] GB Macros and Methods

Benoît Minisini gambas at ...1...
Wed Jan 25 02:06:12 CET 2012


Le 25/01/2012 01:13, Randall Morgan a écrit :
> Hi,
>
> I've been digging around the various components and trying to piece
> together the inner workings. I'm far from done! But I do have a few
> questions:
>
> I plan to port the GNU Scientific Library to Gambas (GSL) using C. The GSL
> is a collection of related high level mathmatic functions. Many of which
> require vectors and matrices.
> I want these to appear to Gambas as gb.GSL.<class>, where class is one of
> the GSL's many classes shuch as "math" for generic mathimatical methods
> like special implementations of POW().

First I strongly suggest to simplify the name of the classes.

I suggest that you use the name of the mathematical objects as class 
name directly. Because a complex is a complex, a polynomial is a 
polynomial, and so on.

Example:

	Dim C As New Complex(R, I)
	Dim P As New Polynomial(...)


As for global GSL methods, the standard is putting them directly in a 
static GSL class.

Example:

	Print Gsl.IntPow2(2)


> It is desired to be able to use the library in Gambas as
> gb.GSL.math.IntPow2(2) which should return a float (double in C) to the
> caller. The function takes in integer as the argument.
>
> With this info in had, it appears that much of this can be done by creating
> C function wrapped in BEGIN_METHOD()/END_METHOD macros, i.e.:
>
> BEGIN_METHOD(INTPOW2, GB_INTEGER x)
>     // Return x^2 using a small int safe method
>     // call gsl native function double gsl_pow_2(int x)
>     GB.ReturnFloat(gsl_pow(VARG(x)))
> END_METHOD

I strongly suggest that you name the implementation function that way:

<class>_<method>

For example: Gsl_IntPow2

Look at a recent component (like gb.dbus), where I follow this scheme.

>
>
> In the header file I need to used the DECLARE_METHOD() to expose the
> methods to Gambas:
>
> DECLARE_METHOD(INTPOW2)

This is not needed, as normally the implementation function is only used 
inside one file, the file that implements the class.

>
>
> Next, in the class file, I need to expose the class to Gambas using the
> Class Desc macro:

Yes.

>
> GB_DESC CMath[] =
> {
>      /* Describe the math class to Gambas */
>      GB_DECLARE("CMath",0), GB_NOT_CREATABLE(),
>
> }
>
> Can you explain the params and the use of GB_STATIC_PROPERTY,
> GB_STATIC_PROPERTY_SELF, GB_STATIC_METHOD, GB_STATIC_FAST_METHOD,
> GB_INTERFACE?

Yes. You can look at the wiki doc, even if it is out of date, to get an 
idea of what these macro do. Or look at the source a component whose 
interface is well known of you.

GB_STATIC_PROPERTY(<name>, <type>, <function>) -> Declare a static property.

<name> is a C string, the name of the property.
<type> is a C string, the property signature.
<function> is the name of the implementation function.

GB_STATIC_METHOD(<name>, <type>, <function>, <arguments>) -> Declare a 
static method.

<name> is a C string, the name of the method.
<type> is the signature of the method return type, or NULL if the method 
returns nothing.
<function> is the name of the implementation function.
<arguments> is the signature of the methods arguments, or NULL if the 
method has no arguments.

GB_STATIC_FAST_METHOD: Don't touch, it is dangerous. :-)

GB_INTERFACE: you won't have any use of that. It is a hacky way of 
declaring that a class implements "something" (an interface), this thing 
being represented by a pointer.

>
> Where does the ID come from in GB_INHERITS?

GB_INHERITS(<class>) -> Inherits a class.

<class> is a C string, the name of the parent class.

>
> Somewhere I need to expose the various classes to GAMBAS. I think the in
> the main or base class file?

You should create a "main.c" file that declares and exports the 
GB_CLASSES array, the GB_INIT() and the GB_EXIT() functions.

>
> GB_DESC *GB_CLASSES[] EXPORT =
> {
>      /* GSL */
>      CGsl,
>
>      /* GSL.MATH */
>      CMath,
>
>      /* GSL.STAT */
>      CStatistics,
>
>      /* GSL.MATRIX */
>      CMatrix,
>
>       ...
>
>      /* GSL.POLYNORMAL */

--> Beware with your dyslexy. :-)

>      CPoly,
>
>      NULL // Looks like all GB_DESC must end with NULL?

Yes, otherwise the interpreter cannot know that the array is finished.

> };
>
> Am I way off base here or on the right track?

You're on the right track.

>
> Ok, I know this is a lot to ask. So I'll make you a deal. If you help me to
> understand all this I will write an English tutorial for creating
> components using C/C++.

It would be cool.

-- 
Benoît Minisini




More information about the Devel mailing list