[Gambas-user] Complex Numbers and Shared Libraries

Tobias Boege taboege at gmail.com
Sun Feb 24 23:33:10 CET 2019


On Sun, 24 Feb 2019, Cedron Dawg wrote:
> Hello all,
> 
> Well, I'd like to ask for some more specific technical advice.
> 
> I am writing a wrapper shared library to access the FFTW library from Gambas.  The design of that library requires that an input and output area be provided to a "preparation step", then subsequent calls use these areas, then they need to be freed.  It is also a requirement that these areas don't move in memory.  Therefore, I am having my wrapper allocate the memory and free it, rather than assume that a Gambas garbage collection won't move it.
> 

Gambas is reference-counted, not garbage-collected, but you're right
in not relying on that.

Gambas has its own Alloc and Free [1] functions for dealing with exactly
these requirements for external libraries. You don't have to write a
C library to give you opaque areas of memory.

You could also have Extern'd malloc and free directly from libc.

> So far, I am able to get the address back to Gambas as a pointer.
> 
> I can read the memory with either Float@ or reading a memory stream.  No problem.  I can write to the memory using a memory stream.  No problem.
> 
> First question:  Is there any other method, particularly one that makes the memory access "look native"?  Similar perhaps to how C allows you to use a pointer with array syntax.
> 

There are embedded arrays [2] which should have a packed representation
in memory like arrays in C, but I don't know if you can cast any pointer
to such an array type and then use it successfully.

> Now we come to the crux of my real question.  The return values from a DFT is an array of complex numbers.  In the FFTW library, a complex number is two adjacent floats in memory, the first being the real part and the second being the imaginary part.
> 
> I seem to have three options:
> 
> 1) Deal with two doubles
> 2) Use the gb.gsl complex
> 3) Use gb.complex
> 
> The first I know I can do.  The other two are mutually incompatible.  Since I am likely to want to use the gsl for more stuff, I think I would like to use #2.
> 
> I've been doing some experimenting and researching, and have not been able to figure out how to get the address of the actual values.  Nor have I been able to read or write complex values to the remote memory area.
> 
> Second question:  Is this possible?
> 

That should be very possible. If you have the two Floats (note: a C float
is a Gambas Single, a C double is a Gambas Float), you can create a complex
number object from them:

  ' ... get re and im from the library ...
  Dim z As New Complex(re, im)

You can get the real and imaginary part back out of the object if you
need to pass them again to the library later.

gb.complex and gb.gsl both allow that.

> I am proceeding under the assumption it is not.  Any opinions on how I am doing things are welcome.  I am still a newbie to Gambas.

If you want to interface Gambas with C libraries, the -by far- cleanest
solution is to write what is called a *native component* for Gambas.
This is a C library itself which is written in the Gambas C framework.
This framework consists of many preprocessor macros and an interpreter API.
At the end of the day, this framework enables you to implement Gambas
classes in C, so that you can access your target library properly in C,
but present it as if it was written in Gambas.

As a corollary, you don't have to wrestle with struct alignment issues
anymore because all access to C structs is done from C code, not Gambas
code. All this translation of struct definitions and functions from a
C library into Gambas Struct and Extern declarations becomes really,
really messy really, really fast.

The downside is that currently native components have to live in the
Gambas source tree and be compiled from there, so you are less flexible
about the distribution of your component. I don't see why that has to
stay like this though. The only thing you really need most of the time
is the gambas.h header which might even be installed into /usr/include
in a hypothetical future.

Regards,
Tobi

[1] http://gambaswiki.org/wiki/lang/alloc
[2] http://gambaswiki.org/wiki/lang/arraydecl

-- 
"There's an old saying: Don't change anything... ever!" -- Mr. Monk


More information about the User mailing list