BlitzMax types and dlls
BlitzMax Forums/BlitzMax Programming/BlitzMax types and dlls
| ||
I have found that it passing BlitzMax types to and from a BlitzMax dll works perfectly, even with other languages. I would recommend declaring the variables as a byte ptr in the main program, and having the BlitzMax dll return the type. DLL function: Function SubmeshSurface_:TSurface(hsubmesh:Int) "win32" GCEnter() Local submesh:TSubmesh submesh=TSubmesh(HandleToObject(hsubmesh)) Return submesh.surface EndFunction Function CountVertices_:Int(surface:TSurface) "win32" GCEnter() Return surface.CountVertices() EndFunction Main program: Global SubmeshSurface:Byte Ptr(hsubmesh:Int) "win32" Global CountVertices:Int(surface:Byte Ptr) "win32" Obviously it is your responsibility to manage the memory, but for types that always get stored in a list and have a Free() command, this approach will work just fine. The only problem I have found is that the BlitzMax dll does not seem to recognize Null when it is passed. When I pass Null to this DLL function from the main program, the dll always thinks that a valid object was passed: Function LoadMesh_:Int(cs:Byte Ptr,oparent:TEntity) "win32" GCEnter() Local parent:TEntity Local mesh:TMesh Local path$ If oparent=Null Notify "null parent" Else Notify "Something was passed, muthafucka!" parent=TEntity(oparent) 'parent=TEntity(HandleToObject(hparent)) path=String.fromcstring(cs) mesh=LoadMesh(path,parent) If mesh Return mesh.handle EndFunction |
| ||
Interestingly, when I got a "null" value from a dll function like this:Function TestObject:Object() "win32" GCEnter() Return Null EndFunction And passed it back to the dll, it was recognized as Null! |
| ||
When the main program passes Null to the dll, and that object is converted into a byte pointer, the value is 8. This makes sense, because of the BMX object offset, which I assume is 8 bytes. I could do this to check if a byte ptr passed to the dll is a null object: If Int(ObjectPointer(parameter:Object))=8 parameter=Null ...but I am a little scared of reading memory not allocated by the program. What is really needed here is a way to convert a BlitzMax object to a pointer and back. BlitzMax does not allows a Byte Ptr to Object conversion. I would like to request this be changed. Type TFoo EndType Local p:Byte Ptr Local foo:TFoo foo=New TFoo p=ObjectToPointer(foo) foo=TFoo(PointerToObject(p)) Function ObjectToPointer:Byte Ptr(o:Object) Return o EndFunction Function PointerToObject:Object(b:Byte Ptr) Return b EndFunction |
| ||
Here's an example with binaries and source: http://www.leadwerks.com/post/objectpointers.zip dll.bmx: Type TFoo Global list:TList=New TList Field name$="I am a foo." Method New() list.addfirst(Self) EndMethod EndType Function GetNullObject:Object() "win32" GCEnter() Return Null EndFunction Function GetObject:Object() "win32" GCEnter() Local foo:TFoo=New TFoo Return foo EndFunction Function SetObject(foo:TFoo) "win32" GCEnter() If foo Notify foo.name Else Notify "Foo does not exist." EndIf EndFunction main.bmx: hlib=LoadLibraryA("dll.dll") Global GetObject:Byte Ptr() "win32" Global SetObject(foo:Byte Ptr) "win32" Global GetNullObject:Byte Ptr() "win32" GetObject=getprocaddress(hlib,"GetObject") GetNullObject=getprocaddress(hlib,"GetNullObject") SetObject=getprocaddress(hlib,"SetObject") Local foo:Byte Ptr foo=GetObject() 'This works fine: SetObject foo 'This works, too: SetObject GetNullObject() 'This crashes: SetObject Null End Here is one workaround to make the dll not crash: Function SetObject(foo:TFoo) "win32" GCEnter() If Int(ObjectPointer(foo))=8 foo=Null If foo Notify foo.name Else Notify "Foo does not exist." EndIf Function ObjectPointer:Byte Ptr(o:Object) Return o EndFunction EndFunction But this feels like a hack and I am very wary of it. I am afraid BlitzMax might be creating empty objects or something other than just handling a data pointer. |