Using callbacks in a DLL
BlitzMax Forums/BlitzMax Programming/Using callbacks in a DLL
| ||
I am running one BlitzMax program and calling a DLL written in BlitzMax with it. I am experiencing some random variable changes, which only happen when I have an error in a dll. It usually happens when I forget to add GCEnter() at the start of a dll function, or when I forget to add "win32" to the end of the function declaration. However, this is now happening when I use my callback function. The function accepts a function pointer, then calls that function for every object in the list: Function dll_ForEachTextureGroupDo(fn:Byte Ptr) "win32" GCEnter() Local callback:Int(handle:Int) callback=fn For texturegroup:TTextureGroup=EachIn TTextureGroup.list If Not callback(texturegroup.handle) Exit Next EndFunction The callback looks like this. (This is a part of the main program): Function Callback:Int(handle:Int) Return True EndFunction So the main program sends the function pointer to the dll, and the dll performs the function for all objects in a list. And the program is actually going like this: EXE stuff DLL stuff EXE stuff DLL stuff EXE stuff Do I need to add GCLeave() or do anything extra like that before the dll calls the callback? |
| ||
No comment? |
| ||
No idea with BMAX, I only know c/c++ for DLLS. |
| ||
Are there any examples of creating a DLL with Max? iv not seen anything of this yet but seen it mentioned a few times. |
| ||
If you use callbacks don't forget to use GCSuspend and GCResume around the callback when you start using Ptrs to stuff Don't know about GCLeave as the DLL stuff is still not officially there but I would say: why not simply test it and see what it does. |
| ||
Because dll errors do not cause consistent visible errors. When the stack is screwed up, you get random variable changes and weird stuff. |
| ||
@Yavin, this has the basics here |
| ||
Hmmmm, I think I will have to avoid callbacks altogether. I must not understand something crucial, because even using a simple callback results in things like my comboboxes become totally black. Obviously something is off in the stack or GC, and it is overwriting program memory. |
| ||
Interesting... Here is the section in the dll that calls the callback: If AppLogCallback<>Null 'If RETURNSTRING<>Null MemFree RETURNSTRING RETURNSTRING=s.tocstring() GCSuspend() AppLogCallback(RETURNSTRING,flags) GCResume() Return EndIf RETURNSTRING is a global byte ptr. It is used to return a string value from the dll. A crash occurs when I use MemFree on the variable RETURNSTRING. Actually, a crash occurs in a different unrelated function, indicating that this probably screws up memory somewhere. What is the proper procedure to use a string this way? Does the byte ptr need to be freed if I am assigning it to a new CString? |
| ||
Ha! I was using a global variable for all my callbacks, and of course, some callbacks call functions in the main program that set callbacks, so my callback function was getting changed! I'm still a little hazy on how byte ptr's should be freed, but I am getting somewhere. |
| ||
memfree is the correct way to free bytePtr memory. But I fear such kind of problems somewhere were to be expected. DLL support is not officially in nor ever mentioned to be anywhere near stable. So what you do is alpha test the feature most likely. I'm quite a BM fan, but for DLL I would suggest using PureBasic, because its threadsafe and supports threads and mutexes. Don't know when or if this will ever be added to BM. |
| ||
Nah, it works great. You just have to understand a few caveats. |
| ||
Basically, yes, in most cases it works :) But that does not always help. And writting wrappers around C++ although its officially supported as "to be importable" is kind of annoying just to prevent the GC from commiting suicide. (if this wrapper is in C or if you do it through management layers in BM does not make a difference out of my sight. Not beeing able to use a C++ object directly without killing the GC in some cases, although I can fully declare it, is a critical problem) |