PureBasic Multi Thread DLL Problem

Blitz3D Forums/Blitz3D Programming/PureBasic Multi Thread DLL Problem

Robin Hossain(Posted 2004) [#1]
Has anyone successfully used a multi-threading PB DLL - that is, a DLL which itself initialises a background process thread.

Any PB DLL that initialises a thread seems to crash in Blitz3D with me.

Also has anyone managed to access (write to) the Blitz Banks RAM DIRECTLY from outside Blitz3D?

Many Thanks


soja(Posted 2004) [#2]
Also has anyone managed to access (write to) the Blitz Banks RAM DIRECTLY from outside Blitz3D?

Yes, you just have to pass the bank as a parameter to your exported function, and make sure it's declared as *. It ends up being a by-reference parameter. The DLL will have the actual memory address where the bank contents are, and all it has to do is overwrite them. You can also do this with a custom type instance.

Is that what you mean?


Robin Hossain(Posted 2004) [#3]
Hi Soja,

I thought I'd tried retreiving the address of the banks from a CALLDLL from Blitz only to find that writing to the actual address from PB then caused Blitz to crash (Page Protection fault - if I remember) - but seeing as you have successfully done this I'll try again.

PS. I'm not trying to return a value from a call to a DLL procedure to a Blitz bank. What I am trying to do is identify where the bank actually is in memeory and then have another exe/dll (from PB) perform calculations from serial data and write its results directly to that Blitz Banks RAM address - so that in Blitz I only have to read from a bank to get the latest result from the exe running seperately in parallel.


AntonyWells(Posted 2004) [#4]
To pass banks using userlibs etc, you have to use the *< character in the decls.

I.e

test(myBank*,size%):"_test@8"


I've used pb+blitz to access memory banks created in blitz.

Although if you want to create a bank in pb and return it you may have to be careful. Alot of pb resources are stupidly nuked when the .dll call ends.

And I believe threading falls under that fate. I tried (and failed) to do the same thing.


Robin Hossain(Posted 2004) [#5]
Thanks Otacon - I'll try that and let y'all know how it went - pity about the threading though - will have to have multiple background EXE's and see if that works...


Robin Hossain(Posted 2004) [#6]
Otacon,

I can write to banks no problem from the called DLL, but because multithreading fails - I resorted to passing the address to another PB exe - when this PB exe tries to access the same address is when I get the errors - do you think this is Windows application memory protection - or should it be working ?


skidracer(Posted 2004) [#7]
You can only share memory between processes that has been allocated with the GlobalAlloc system command as your second process will generate a memory exception accessing memory that is in another process's address space (blitz banks etc.)


Seldon(Posted 2004) [#8]
I think it's never possible to share memory between processes even if you use GlobalAlloc() , that's what MS-API says:
"In the linear Win32 API environment, there is no difference between the local heap and the global heap."

The Global/LocalAlloc() difference is meant for the old Win3.1 environment.

In Win32 you can share memory using several methods:

1) You can use a system wide DLL (all processes will LOAD the same copy of the DLL and variables are static, each program that will access the DLL, will get the same values of variables used in the DLL).

2) Memory mapped files. It's a great way. I used them to make a fast communication between programs using "ports" you set by name (sort of Amiga :). I have a DLL with funcions like OpenPort("Name") and SendData("Name") and all programs that have opened that port can read/write data from/to it. It works fine also with Blitz programs.

3) There is a funcion to retrieve the "real" memory address allocated by another process and get a valid pointer to it.. sorry I don't remember the name of such API call. This seems the fastest method (you only pass a pointer) , but I don't know how much "the system" takes to do that.

Look for "shared memory" on MSDN.


AntonyWells(Posted 2004) [#9]

Otacon,

I can write to banks no problem from the called DLL, but because multithreading fails - I resorted to passing the address to another PB exe - when this PB exe tries to access the same address is when I get the errors - do you think this is Windows application memory protection - or should it be working ?


See above really. After I couldn't get it working with threads the normal way I did what most coders do. blamed my tools, and gave up. ;)

Memory sharing/objects etc are commonly a bitch with pb .dlls though(To the point of where I no longer even consider using it) .dlls I create in Vc6++ never have these problems, so you might want to look into that.


Inner(Posted 2004) [#10]
it has nothing to do with shared memory, it's the fact that PB DLL's are "NOT" thread safe for strings at least.


Bug Face(Posted 2004) [#11]
This is not a _process_ memory problem if he is creating a thread. The .dll will be loaded into the same memory map as the calling application (that's what does on in the LoadModule() function in Windows). Threads can share memory within the same process. I do this kind of thing, between different programming languages all the time. Just never between Blitz and PB.

I don't have PB but my best guess is the chap who pointed out that PB releases loads of resources when the DLL call returns. Make sure you are not dependant on anything that might live on the stack or only for the duration of the function call. If you can't get it to work that way... Hell grab a C++ compiler and build it in a language you can control :-)

Bug


Robin Hossain(Posted 2004) [#12]
Soja, Otacon, Skidracer, Seldon, Inner and Bug Face - I appreciate your support.

It would seem that what I am trying to do in the way I was hoping cannot be easily acheived between PB and Blitz. It does seem as if that accessing RAM used by one application by another application is prohibited in Windows unless this can be disbled somehow. However, there must be a way to do it - as RAM drives do a similar thing but as a device managed by a DLL. I also understand that in C, windows wide global memory can be allocated.. I'll still try and give it a few more bashes and let you know.

Regarding the PB thread - 'not safe' issue - yes, I'm aware that PB uses a single buffer for all string operations - so when a thread begins using strings its using the same buffer as any other thread or the main PB program - hence corruption of the string eventually occurs. But as soon as a DLL built in PB creates a new thread (even with nothing going on in the thread) Blitz3D will crash.

It may be worth noting other PB DLL issues. You generally need to use the ProcedureCDLL instead of the ProcedureDLL - I've found that after about 3000 calls to a ProcedureDLL type DLL Blitz will crash also.


Robin Hossain(Posted 2004) [#13]
Oh - One more thing.

I only trust DLL usage with PB DLLs when I use a CallDLL from Blitz the decls seems quite unreliable after iterative tests. But CallDll seems to work as intended so far(not for the problems discussed above , but for general straight forward DLL usage).