[Gambas-user] Working with .so library
Cedron Dawg
cedron at exede.net
Mon Jun 24 16:10:48 CEST 2019
What you need is a pointer to a pointer.
libfptr_handle fptr;
libfptr_create (&fptr);
In C, the first line is a varibale declaration allocating space for a pointer called "fptr". The second line is the function call where you are passing the address of the pointer (a pointer to the pointer) so the routine can stuff the pointer with a value. So in Gambas, your call should be something like:
dim a, b as pointer
b = varptr(a)
libfptr_create(b)
Then "a" is the variable you can pass to the other routines. I haven't tried it, but it should work.
On the other hand, I have found it cleaner when interfacing to external C libraries to write my own shared library as an inbetween. That way you can hide this kind of detail down in the C code.
You can find an example here for the FFTW library:
https://forum.gambas.one/viewtopic.php?f=4&t=689
Ced
----- Original Message -----
From: "Admin" <admin at allunix.ru>
To: "user" <user at lists.gambas-basic.org>
Sent: Monday, June 24, 2019 9:13:22 AM
Subject: Re: [Gambas-user] Working with .so library
Greetings, people of Gambas!
So, this thread is couple of years old now, and yet I want to thank
everyone again, who helped me with that issue. Everything worked out
just fine, I was able to create a working cash register software which
lived through at least thirty versions, was cloned on github by a few
people to create similar programs for their businesses, and the emails I
got from them are very satisfying. It works, and many good people saved
a lot of money dodging the bullet of mandatory Windows installations to
support those devices that we use nationwide.
So now there's another challenge. Recently linux driver for those
devices was updated to a new major version, and it is basically a whole
new .so library. In previous versions, as I've mentioned here, we needed
to create an interface with the driver from our program using
CreateFptrInterface function. This function returned a pointer to a
driver, and thanks to you kind people I was able to understand that we
needed such a structure in gambas to work with it:
Extern CreateFptrInterface(ver as integer) as Pointer
Public drv as Pointer
Public Sub Form_Load()
drv = CreateFptrInterface(12)
End sub
and now we basically have drv as a pointer to a Driver, wich can then be
passed to any library function, so, for example, Beep(drv) will make a
device to create a sound (that is if we declare Extern Beep(p as
pointer) ofcourse).
That structure worked until new Driver was created very differently. The
new .so library is also documented, but, as always, only for those who
write their applications in C++, and now it says that we need to
initialize the Driver like this:
libfptr_handle fptr;
libfptr_create (&fptr);
Well, I tried to apply the same knowledge that I've gained with the
previous version and it did not help.
libfptr_handle does not seem to be a library function at all, yet it is
described in a header file (which is also available here:
http://gazizova.net/pub/install/_Devices/atol-30f/10.2.0/ios/fptr10.framework/Headers/libfptr10.h)
libfptr_create IS a library function, but I could not figure out how to
corretly call it.
At first I thought that logic is the same: we call a function that
creates an interface and it gives us back a pointer to a Driver, so in
Gambas it should look something like:
Extern libfptr_create() as Pointer
Public drv as Pointer
Public Sub Form_Load()
drv = libfptr_create()
End sub
but ofcourse that is kind of strange, because function libfptr_create as
it seems to be still wants some argument. And it sure looks like this
argument is the pointer. And yes, if I call a function like this, I get
drv = 0. So, then, should I call this function like this:
Public Sub Form_Load()
libfptr_create(drv)
End sub
putting (p as Pointer) in Extern description ofcourse.
But no, that does not work either. In that case Gambas just segfaults,
wich, as I now know, just indicates that parameters passed to an
external function are of wrong type or just there should be more or less
of them. Looking inside the log file of a Driver I can also see another
interesting fact: If I, just out of curiosity, call a function
libfptr_create and pass some random number to it declaring it as integer
(just like it was in a previous version of a driver where it required to
have a driver version as integer passed with CreateFptrInterface) - it
definitly initializes to a, say, much further point then if I pass a
pointer to it or nothing at all, and fptr becomes equal FFFFFFF. If I
pass not an Integer, but a random string, the driver initializes to that
same point, but ftpr stays equal 0. I mean a structure like fptr =
libfptr_create(12345) or fptr = libfptr_create("test")
I've tried a lot of different combos but still had not figured it out,
how do I initialize in Gambas what initializes in C++ like this:
libfptr_handle fptr;
libfptr_create(&fptr);
So, as always, any advice will be much appriciated!
Best regards,
Dmitry.
More information about the User
mailing list