Because the dll has its own string heap, this is not guaranteed to work even if you could get the address of myStringVariable, which is why you shouldn't.Libprocedure(inparameters1, inparameter2, ..., AddressOf(myStringVariable))
How to obtain the address of a string variable?
Re: How to obtain the address of a string variable?
Re: How to obtain the address of a string variable?
This extra string heap thing, seems to be a fairy tale.
I tested it and compared the addresses of the created string data
with other string data created without the help of the library:
-> They are in the same memory area,
practically touching each other front and back.
I testet the memory behaviour
assigning the same string data via string literal one time
via library call another time and found the same behaviour.
(Testet with my linux system yet.)
Why should this use another string heap?
After all it is not another process creating the strings,
but only code stored in another file.
I tested it and compared the addresses of the created string data
with other string data created without the help of the library:
-> They are in the same memory area,
practically touching each other front and back.
I testet the memory behaviour
assigning the same string data via string literal one time
via library call another time and found the same behaviour.
(Testet with my linux system yet.)
Why should this use another string heap?
After all it is not another process creating the strings,
but only code stored in another file.
Re: How to obtain the address of a string variable?
The different heap stuff is on Windows, on Linux I don't know. Experience shows you can free memory from the wrong heap on Windows, but it's not legal.
When you test stuff and it works, that does not mean it's correct and will always work in the future.
Let's put it this way: How would the dll find the string heap of the main program? Answer: It can't, because the main program may not even be a PB program, so the dll can't even assume the main program uses a separate string heap.Why should this use another string heap?
When you test stuff and it works, that does not mean it's correct and will always work in the future.
Re: How to obtain the address of a string variable?
Testing with W2k:
-> something is different!
After assigning a string via DLL,
I find that this string data are at another location
(say 32 M instead of 8 M)
-> AND: Now newly assigned strings (no DLL used) are
also put in the new area!
This seems to apply to any strings requiring a new location,
but not to the ones that can be expanded in the old area
and therefore need no relocating.
This does not only indicate to me, that your "another heap theory"
could apply to the windows version,
but I would also speculate there is a relation to your dll string memory leak bug
and it might be related to this.
-> something is different!
After assigning a string via DLL,
I find that this string data are at another location
(say 32 M instead of 8 M)
-> AND: Now newly assigned strings (no DLL used) are
also put in the new area!
This seems to apply to any strings requiring a new location,
but not to the ones that can be expanded in the old area
and therefore need no relocating.
This does not only indicate to me, that your "another heap theory"
could apply to the windows version,
but I would also speculate there is a relation to your dll string memory leak bug
and it might be related to this.
Re: How to obtain the address of a string variable?
I don't know where you got the idea that I speculate and guess about things. When I say the dll has its own string heap, I say that because that's the way it is.This does not only indicate to me, that your "another heap theory"
could apply to the windows version,
Code: Select all
; compile to messagebox.dll
Global StringHeap
ProcedureDLL DllMain()
!EXTRN _PB_StringHeap
!mov eax, [_PB_StringHeap]
!mov [v_StringHeap], eax
MessageRequester("Dll string heap", Str(StringHeap))
EndProcedure
Code: Select all
; save to same directory and messagebox.dll and run
!EXTRN _PB_StringHeap
!mov eax, [_PB_StringHeap]
!mov [v_StringHeap], eax
MessageRequester("Main string heap", Str(StringHeap))
OpenLibrary(0, "messagebox.dll")
f = GetFunction(0, "DllMain")
CallFunctionFast(f)
CloseLibrary(0)
Re: How to obtain the address of a string variable?
Thanks for your code Trond.
I tried to use it with linux, but got a linker error:So I assume this not applicable to linux in that way.
As I see it, new Windows versions may break your old code anyways.
You can only guess, how the conditions may be in the future.
When you know, how the conditions factually are,
you can adapt to them in a workable way (if at all possible).
I admit, that you should prepare for probable possibilities,
but this is also a matter of what your choices are
and how expensive each one is...
The only real alternative, I see (except for not having the procedure in a different library at all ...),
is something like Demivec suggested or maybe letting the caller create a buffer,
that the called procedure then can fill.
All the "alternatives", I could think of as yet, look kind of disadvantageous and clumbsy to me.
Besides, I'm using the linux version most of the time.
The code can and will be changed, as long as it is used,
if something is not good enough it will be made better (if possible).
I tried to use it with linux, but got a linker error:
Code: Select all
...: undefined reference to '_PB_StringHeap' ...
As I see it, new Windows versions may break your old code anyways.
You can only guess, how the conditions may be in the future.
When you know, how the conditions factually are,
you can adapt to them in a workable way (if at all possible).
I admit, that you should prepare for probable possibilities,
but this is also a matter of what your choices are
and how expensive each one is...
The only real alternative, I see (except for not having the procedure in a different library at all ...),
is something like Demivec suggested or maybe letting the caller create a buffer,
that the called procedure then can fill.
All the "alternatives", I could think of as yet, look kind of disadvantageous and clumbsy to me.
Besides, I'm using the linux version most of the time.

The code can and will be changed, as long as it is used,
if something is not good enough it will be made better (if possible).
Re: How to obtain the address of a string variable?
Assume you don't care about heaps and just want nice, readable and typable code, have you considered this? Multiple threads can call any procedure at any time and it should work as long as threadsafe is enabled.
Code: Select all
;- In library:
Procedure ReturnString(String.s)
*M = AllocateMemory(Len(String))
PokeS(*M, String)
ProcedureReturn *M
EndProcedure
ProcedureDLL LibraryProcedure(id)
A.s = "asdf sdf asdfoq " + Str(id)
ProcedureReturn ReturnString(A + "! (you can even use a string expression)")
EndProcedure
;- In main program:
Procedure.s ReceiveString(*M)
S.s = PeekS(*M)
FreeMemory(*M)
ProcedureReturn S
EndProcedure
A.s = ReceiveString(LibraryProcedure(123))
Debug A
Re: How to obtain the address of a string variable?
Just a reminder, you would need to make some adjustments to the AllocateMemory() if unicode is used. You would also need to include memory for the Null.Trond wrote:Assume you don't care about heaps and just want nice, readable and typable code, have you considered this? Multiple threads can call any procedure at any time and it should work as long as threadsafe is enabled.
Code: Select all
Procedure ReturnString(String.s)
*M = AllocateMemory((Len(String) + 1) * SizeOf(Character))
PokeS(*M, String)
ProcedureReturn *M
EndProcedure
Re: How to obtain the address of a string variable?
Right, I forgot.
Re: How to obtain the address of a string variable?
Thank you Trond and Demivec.
This seems workable,
but wouldn't the called library allocate the memory in its heap
and the memory the be freed by the caller side,
similar to my string approach?
What I like less about this approach is, that it requires some copying of strings.
I would like to avoid creation of additional strings and copying of them as
much as possible.
Once I had an application, that performed very slow in some circumstances.
I traced it to repeated string manipulations that probably went slow
when it required some kind of garbage collection.
Then I replaced the string handling by an approach with (reusable) memory buffers
and the application performed serveral orders of magnitude faster.
This seems workable,
but wouldn't the called library allocate the memory in its heap
and the memory the be freed by the caller side,
similar to my string approach?
What I like less about this approach is, that it requires some copying of strings.
I would like to avoid creation of additional strings and copying of them as
much as possible.
Once I had an application, that performed very slow in some circumstances.
I traced it to repeated string manipulations that probably went slow
when it required some kind of garbage collection.
Then I replaced the string handling by an approach with (reusable) memory buffers
and the application performed serveral orders of magnitude faster.
Re: How to obtain the address of a string variable?
I added an "Edit for future visitors" in my entry post above,
to show a way I found to get the address of a string variable
into a pointer.
to show a way I found to get the address of a string variable
into a pointer.