[Gambas-user] Extern howto/tutorial

Benoît Minisini gambas at ...1...
Wed Aug 25 22:12:14 CEST 2010


> Benoît Minisini ha scritto:
> >> Hi,
> >> 
> >> I finally wrote the tutorial about using external declarations.
> > 
> > This is not HTML, but plain text. If you can make an HTML version of your
> > document, with formatted text, I will be able to add it to the wiki.
> 
> Mmm... this is an excerpt from the first lines of "External-howto.html",
> the file attached to my previous message:
> 
>     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>     "http://www.w3.org/TR/html4/loose.dtd">
>     <html>
>         <head>
>             <meta http-equiv="Content-Type" content="text/html;
>     charset=UTF-8">
> 
> 
> This seems HTML to me... what document are you speaking about? Perhaps
> the .t2t one?
> 

No: there is no HTML at all in your mail.

> >> In the Drum Machine project, after having verified that it works
> >> correctly using pointers for read/write, I tried to create a new class
> >> which should be a gambas representation for an alsa event (which is a C
> >> struct). It does not work, and I don't know how to debug it (well, I
> >> could, using gdb or similar, but I was looking for a more direct way).
> > 
> > Give me the C declaration, and your class declaration, and I will be able
> > to see if they correctly match.
> 
> Both are contained in the attached files - the C declaration, along with
> explanation and unrolling of structs/typedef/#define and so on, in the
> document; the Gambas class trying to emulate the C declaration, in the
> project "Gambas2-Drummachine....". For your convenience, I will repeat
> both at the end of this email.
> 
> > It is explicitely said that "WRITE #Pointer" is not supported anymore in
> > Gambas 3, in the WRITE documentation page. And so on for the READ
> > instruction.
> 
> Sorry, I think that it is not so clear. "No more supported", or
> equivalent semantics, is totally absent from the page. It is true that
> there is a frame specifying the syntax for READ in Gambas3, but it
> speaks only about "READ #Stream". This makes me think that the "READ
> #Stream" syntax or behavior changed, not necessarily that pointers are
> no more valid. Perhaps would be better to say something more in the
> first frame, the one just below the title of the page: "WARNING! The
> syntax has changed in Gambas 3. READ/WRITE with pointers is no more
> supported in Gambas 3. See below."

That is explicitetly mentioned in the READ & WRITE documentation page. See the 
joined screenshot if you don't trust me. :-)

> 
> You said that you removed this syntax because of possible problems with
> memory alignment. What about BytePtr(), SinglePtr() and the alike? Do
> they not suffer from the same problem? (Just a curiosity).
> 
> > The Gambas 3 structures were implemented for the use of extern C
> > structures. Moreover, in Gambas 3, you can now use Gambas functions as C
> > function pointer (as known as "callbacks") almost transparently.
> 
> I know... it was me that kindly requested that feature, I suppose... :-)
> And, apropos...
> I saw that alsa does not really provides a callback - there is something
> about in an undocumented source (an utility for alsa). Instead, what
> alsa provides, is a file descriptor which can be poll()ed or select()ed.
> Then I have seen a source for QT, which uses this capability. It seems
> the QT has a way to pass it a file descriptor, so it can raise events
> intermixed with GUI events. Glib too has something similar. I thought to
> use or fool some gambas stream to obtain the same result... but perhaps
> you have a better idea.

Actually the interpreter can do it, but there is no function in the language 
for that. I will think about a solution... Maybe a new stream object.

> 
> Now let us see the problem about the alsa (musical) event structure.
> Giving that I made it to work, probably I did understand that structure
> and, if I only had a simple way to debug my gambas implementation, I
> would have had success. The alsa declaration is:
> 
>     snd_seq_event_type_t    type
>     unsigned char           flags
>     unsigned char           tag
>     unsigned char           queue
>     snd_seq_timestamp_t     time
>     snd_seq_addr_t          source
>     snd_seq_addr_t          dest
>     union {
>        snd_seq_ev_note_t    note
>         ...
> 
> The first field, type, is a byte. The fifth field, time, is a union
> having a total length of two ints, eight bytes in total.
> The source and dest fields are struct composed of two bytes each. After
> this fields, that are common to every alsa event, comes a specialized
> part for every different event. I only used the snd_seq_ev_note_t.
> 
> My gambas translation is:
> 
>     ' Gambas class file
> 
>     ' object data to simulate a C struct
> 
>     type AS Byte            '    snd_seq_event_type_t type
>     flags AS Byte           '    unsigned char flags
>     tag AS Byte             '    unsigned char tag
>     PUBLIC queue AS Byte    '    unsigned char queue
>     time_tick AS Integer    '    snd_seq_timestamp_t Time
>     time_dummy AS Integer   '    snd_seq_timestamp_t Time (2 part of union)
>     PUBLIC sourceq AS Byte  '    snd_seq_addr_t source (source client)
>     PUBLIC sourcep AS Byte  '    snd_seq_addr_t source (source port)
>     PUBLIC destq AS Byte    '    snd_seq_addr_t dest (dest client)
>     PUBLIC destp AS Byte    '    snd_seq_addr_t dest (dest port)
> 
>     ' note on fields of union {   snd_seq_ev_note_t note ...
>     channel AS Byte
>     note AS Byte
>     velocity AS Byte
> 
>     ' a few bytes as filler
>     dummy1 AS Integer
>     dummy2 AS Integer
>     ...
> 
> If you can use MIDI, or you have a soft synth like timidity, you can try
> to run the project to see what is going on.
> In FMain.class, in the subroutine btLegato2_Click(), you find:
> 
>     ' alsa.playnoteobj(-10 * i, 0, 60 + i, 100, 20)
>     alsa.playnote(-10 * i, 0, 60 + i, 100, 20)
> 
> Decomment the first line and comment-out the second. The second line
> prepares a C struct as the one above, using pointers to write in a
> memory region previously allocated, once for the whole life of the
> running program. The first line instead, tries to do the same by using a
> gambas class. An instance of that class is created once, and then
> repeatedly written to to set the various fields; finally, a pointer to
> the instance is passed to alsa, but alsa replies with "invalid
> argument". My machine is a 32-bit AMD Duron, with a Debian stable
> distribution; the test was made with gambas 2.0.0.
> 
> Best regards,
> Doriano
> 

Note that 'WRITE #p, 0, 1' does not write one byte, but only the integer 0 on 
four bytes. You must do 'WRITE #p, chr$(0), 1'

WRITE #p, outq writes four bytes as outq is an integer, not one byte.

And so on... I think you must check all your use of the WRITE instruction, 
which write a number of bytes that depends on the datatype of its second 
argument.

In Gambas 3, you say explicitely what datatype you want to write (WRITE 
#Stream, Expression As Datatype).

As for the use of an object instead of a memory allocation, I don't know. I 
must study that in detail. When passing an object to an extern function, the 
extern function receives the memory address of the first field. So now I must 
check that all datatypes match, and that there is no alignment problem.

Regards,

-- 
Benoît Minisini
-------------- next part --------------
A non-text attachment was scrubbed...
Name: read.jpeg
Type: image/jpeg
Size: 131444 bytes
Desc: not available
URL: <http://lists.gambas-basic.org/pipermail/user/attachments/20100825/21e645c1/attachment.jpeg>


More information about the User mailing list