[Gambas-user] Arrays of Structs - how to - and curious debug message

John Anderson johna at starflightinc.com
Tue Jun 15 19:00:30 CEST 2021


On 6/14/2021 12:34 PM, Brian G wrote:
> And one more example using embedded structures and arrays, showing how to call c fucntions with arrays and structures
> how to redefine the c call to allow muliple uses of the function with differing inputs to that function
>
> ' Gambas module file
>
> Public Struct newit
>    x[20] As Byte
> End Struct
>
> Public Struct byeit
>    c As Integer
>    b As Float
>    e[20] As Struct Newit
> End Struct
>
> Public Struct Hello
>    b As Integer
>    c As Integer
>    d As Long
>    e As Float
>    f As Struct Byeit
>    g[20] As Struct Byeit
> End Struct
>
> ' We will use memcpy for two purposes , get the real address of the data, actually copy the data
>
> Extern memcpy(dest As Hello, src As Hello, len As Integer) As Pointer In "libc:6"
> Extern Arraymemcpy(dest As Pointer, src As Pointer, len As Integer) As Pointer In "libc:6" Exec "memcpy"
>
> Public b As Struct Hello
> Public c[20] As Struct Hello
>
> Public Sub Main()
>    b.b = 43
>    'Static xx As Struct Hello
>    
>    Dim a As Variant = b
>    Dim e As Hello = c[1]  ' these just set pointers
>    Dim f As Hello = c[2]
>    Dim g As Hello = c[3]
>    g.d = 500
>    g.e = 3.67
>    c[3].g[0].e[0].x[0] = 32
>    ' Calc Struct length do pointer math c[1]-c[0]
>    Dim iStructLen As Integer = memcpy(c[1], c[1], 0) - memcpy(c[0], c[0], 0)
>    
>    Print "Struct len = "; iStructLen, "Dest Values before copy ", f.d, f.e, f.g[0].e[0].x[0]
>    'Copy one entry to another
>    memcpy(f, g, iStructLen)
>    Print c[2].d, c[2].e, c[2].g[0].e[0].x[0] ' g = c[3] f = c[2]
>    a.b = 45
>    
>    Print a.b, b.b
>    ' Display the actual address Of Each element And root
>    Print memcpy(a, a, 0), memcpy(b, b, 0), arraymemcpy(VarPtr(c), VarPtr(c), 0), memcpy(e, e, 0), memcpy(f, f, 0), memcpy(g, g, 0)
>    Print VarPtr(a), VarPtr(b), VarPtr(c)
>    Print "Hello world"
>
> End
>
>
> "Failure is the key to success;
>   each mistake teaches us something"  .. Morihei Ueshiba
> Brian G
>
Thanks Brian, I got that response on Bugtracker too.  I guess what had 
me fouled up is (at least until yesterday)  is that the Wiki Extern and 
Wki How To  didn't make it very clear that you have to use the struct 
definition to send pointer to sruct.  I interpreted the wiki as : 
declare struct "abc" and then struct abc gets converted to pointer in 
EXTERN function call.  I guess it makes more sense now that I see a 
concrete example.  I thought EXTERN command would look at the instanced 
struct name and know how to compute the pointer to data...but you have 
to setup EXTERN call to match up to the array struct you want to send .  
Oops.

I think a good example like yours would make an excellent clarification 
to wiki.  That would save users lots of time.

There is a big distinction between copying Pointers in gambas - like 
MySvar = MySVarArray[5]: that will work.  BUT you have just copied 
pointers, not data contents.

I need to copy data contents between array of struct to another unique 
struct, as you are showing.

As C user - It seems a little odd that there is no way in Gambas to 
retrieve a pointer to struct array without calling C function.  But then 
again array of structs isn't really a real array - which is the same 
type of problem we run into with dotNet where the data has to be 
marshaled around to and from compatible C call.  It really slows 
everything down on dotNet when you need a lot of fast C calls.

Our conversion problem is:  We've got dozens of structs and array of 
struct.  It's not my choice - we have to interface with other vendors' C 
code for machine controls, machine vision etc.  And we now have to 
maintain several versions of the same EXTERN memcpy call for each struct 
array type - each with different parameter calls to define EXTERN calls 
for different arrays.  And Benoît says he wont be making Struct[] any 
sort of type with built-in .Copy or .VarPtr method, etc.  OK.  That's 
how Gambas works, and I can't change that.

Without thinking too much (and is probably bad idea):  It would be cool 
if somehow Struct[] were the parent of all storage class datatypes (and 
if only one element in the array you ditch the square brackets) but we 
don't have that option now, and I don't even know if that could work for 
interpreter.  Dang.

SO - We are deciding to re-evaluate the situation and see if it isn't 
better to put everything into C anyway, and move away from GBasic 
dialect style of storage altogether.  We have to move a lot of data 
around fast - in between each video frame sometimes - so it might be 
better to stick to straight C altogether - which puts our data as close 
as possible to our control system calls.

Thanks Again!!

-John






More information about the User mailing list