Passing opaque structs between BMax and C

BlitzMax Forums/BlitzMax Programming/Passing opaque structs between BMax and C

AdamRedwoods(Posted 2010) [#1]
I feel it can't be done, which then I'd need some C wrapper guidance.

So I am trying to create a Quicktime mod for BMax (Win32 thus far). Using the QTSDK I am able to tap into the ".lib" files.

Say you have:
Function NewGWorld:Int(GWorldPtr:Byte Ptr, monitorPixelDepth:Short=0, bounds:Byte Ptr, cTable:Int=0, GDevice:Int =0, flag:Int=0)


Where NewGWorld is looking for a pointer to a struct "GWorld". Well, I don't have a clue what GWorld is. So instead, I create an opaque type "TGWorld".

Type TGWorld
	Field data:Byte[4096]
EndType


I pass my Type to function NewGWorld as:
r=NewGWorld(Varptr(gwptr),0, bounds.bptr, 0, 0, 0)


which I can then pass to another function later (note it does not look for a pointer):
'' extern "C" is Function SetMovieGWorld:Int(QTMovie:Object, GWorldPtr:Object, gdhandle:Object=Null)
r = SetMovieGWorld(movieptr, gwptr, Null)


sneaky, but I don't get an error back (Quicktime errors are negative numbers, which I usually convert using an uint-to-signed int function).

But does it work after I go through all the other setup? No.

Questions:
- Is it possible to do what I'm doing? It seemed to work for some functions, but not others.
- Do I need to setup the exact Field Type? Or are passing C structs and BMax Types an insane way to spend the afternoon?
- What would be better to have a wrapper do this. And I'd like to see an example if possible, since I'm pretty lame when it comes to C coding.


Otus(Posted 2010) [#2]
If you need to pass structs around and not modify them in BlitzMax, just call them all Byte Ptr.

If you need to modify/access their contents, you need to look at Extern types. The help section is pretty minimal, but I can send you some sample code if you need it.


AdamRedwoods(Posted 2010) [#3]
Otus, thanks for your assistance!

Question:
I am attempting to allocate and control the structs in BMax. So how would I properly allocate a place for the Byte Ptr? (I thought this is what the Type definition would do?)

Could I use gwptr[4096] as a byte array and then pass the pointer?


Otus(Posted 2010) [#4]
If you want to allocate in Blitz, you need to know the size of the struct. Then either create a Byte array if you want the GC to manage the memory or use MemAlloc for manual management.

Arrays are automatically converted into a pointer to the first element if you assign or pass them as such.
Extern
Function blah(thing:Byte Ptr)
End Extern

Local arr:Byte[256]
blah(arr)



AdamRedwoods(Posted 2010) [#5]
Cool. Then how do I handle the other extern function that needs not a pointer to the struct, but the struct itself?


Gabriel(Posted 2010) [#6]
BlitzMax doesn't pass objects by value. You'd have to wrap the function with a function in C which dereferenced the pointer and passed the struct by value.


AdamRedwoods(Posted 2010) [#7]
Yeah, that's the conclusion I'm coming to. (Although I did get close.)

So then how would the wrapper work? I started it based on Brucy's examples, but I am getting errors like crazy. The biggest being that the headers are not being found.

Question:
I think this is a MingW thing, but how do I point MingW in the right place? Does the file need to be a module before I can do this or can I keep everything in one "test" file for now?

Beginning wrapper:


Thanks for all your help.


Otus(Posted 2010) [#8]
So then how would the wrapper work?

Basically just:
struct some_struct;
void some_func(struct some_struct arg);

void blitz_some_func(struct some_struct *arg)
{
  some_func(*arg);
}