Passing opaque structs between BMax and C
BlitzMax Forums/BlitzMax Programming/Passing opaque structs between BMax and C
| ||
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. |
| ||
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. |
| ||
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? |
| ||
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) |
| ||
Cool. Then how do I handle the other extern function that needs not a pointer to the struct, but the struct itself? |
| ||
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. |
| ||
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. |
| ||
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); } |