Page 1 of 1

Array and Pointer...

Posted: Wed Jun 20, 2007 7:41 pm
by Flype
when working with DLL and we need to return an array of strings, one the best solution can be something like this :
(inspired by the post here : http://www.purebasic.fr/english/viewtopic.php?t=27675)

DLL CODE :

Code: Select all

#MAX_ENV = 100

ProcedureDLL.l GetEnv(*n.Long) 
  
  Static Dim env.s(#MAX_ENV)
  
  If ExamineEnvironmentVariables()
    
    *n\l = 0
    
    While (*n\l < #MAX_ENV) And NextEnvironmentVariable()
      env(*n\l) = EnvironmentVariableName() + " = " + EnvironmentVariableValue()
      *n\l + 1
    Wend
    
    ProcedureReturn @env()
    
  EndIf
  
EndProcedure
CODE TEST :

Code: Select all

If OpenLibrary(0, "env.dll")
  
  *env = CallFunction(0, "GetEnv", @n)
  
  If *env 
    
    Dim env.s(n) 
    
    env() = *env
    
    For i = 0 To n - 1
      Debug env(i)
    Next
    
  EndIf
  
  CloseLibrary(0) ; corrected
  
EndIf
here, everythings ok.


my question is (from the same DLL code) :

is the code below legal ? it works but is it really futur proof ?

Code: Select all

Structure TABLE
  s.s[0]
EndStructure

If OpenLibrary(0, "env.dll")
  
  *env.TABLE = CallFunction(0, "GetEnv", @n)
  
  If *env
    
    For i = 0 To n - 1
      
      Debug *env\s[i]
      
    Next
    
  EndIf
  
  CloseLibrary(0)
  
EndIf

Posted: Wed Jun 20, 2007 9:27 pm
by Psychophanta
Not sure but it seems related to this:
http://www.purebasic.fr/english/viewtopic.php?t=17120
So it is not safe at least you allocate the needed memory amount.

Posted: Wed Jun 20, 2007 10:35 pm
by Flype
but what if the memory is already allocated by using in the dll : 'Static Dim' :?: it seems ok.

Posted: Wed Jun 20, 2007 11:32 pm
by Psychophanta
Oh! sorry, what a sillyness y wrote.
I said nothing :!: :oops:

Yes, i think it is safe.

Posted: Thu Jun 21, 2007 7:56 am
by akj
@Flype,

Running PB 4.10 B2 under Windows ME, the SECOND test code works perfectly, but the FIRST test, after outputting the results correctly, goes into a infinite loop with the last line (EndIf) repeatedly generating the error "Invalid memory access". This still happens even after adding the missing CloseLibrary(0) statement.

Posted: Thu Jun 21, 2007 8:02 am
by Flype
@akj
:shock:

freak, fred ?

Posted: Thu Jun 21, 2007 2:45 pm
by Flype
should i put it in the bug section ?

as i can't see where this is the fault of the final programmer...

Posted: Thu Jun 21, 2007 3:23 pm
by freak

Code: Select all

    env() = *env 
This kind of assignment is not supported in PB.

You can run into trouble with the automatic string cleanup inside arrays etc, which is probably the case here.

Posted: Thu Jun 21, 2007 3:44 pm
by Psychophanta
So then the 2nd example is safe, but the 1st one is not.

Posted: Thu Jun 21, 2007 3:52 pm
by freak
You should consider the string array to be readonly though.
Because the Dll and main program will use different heaps for their string allocation,
modifying the strings from the main program could be trouble.

Posted: Thu Jun 21, 2007 4:13 pm
by Psychophanta
Different heaps?
Isn't supposed that dll and exe point to the same address to get and/or set data on it?
EDIT:
freak wrote:the Dll and main program will use different heaps for their string allocation.
This test shows the heap is the same:

Code: Select all

;DLL:
ProcedureDLL AttachProcess(instance)
 Global Dim Array.s(5)
EndProcedure
ProcedureDLL.l CreateArray()
  For i=0 To 5
    Array(i)="Line "+Str(i)
  Next
                MessageRequester("dll point to:",Hex(@Array()))
  ProcedureReturn @Array()
EndProcedure

Code: Select all

;EXE:
Structure array
  item.s[0]
EndStructure
If OpenLibrary(0,"dll_test.dll")
  *var.array=CallFunction(0,"CreateArray")
                MessageRequester("exe point to:",Hex(*var))
  For i=0 To 5
    MessageRequester("hi",*var.array\item[i])
  Next
  CloseLibrary(0)
EndIf

Posted: Thu Jun 21, 2007 8:19 pm
by Flype
@freak, and all.

thanks a lot for clarifying this behaviour.


i have still a short one :

why 'env() = *env' is compiled without error if this is forbidden ?
what's the use... it's pretty dangerous to let guys like us to allow playing forbidden games :D
a debugger warning, or compiler error might be added.

Posted: Thu Jun 21, 2007 8:22 pm
by Flype
hmmm, maybe i missed one thing.

so i understood, and it's ok : env() = *env is not legal between pb-dll<-->pb-prog

but is it ok inside a standalone pb-prog (no dll stuff) ?


no legal in all case ?


(i'm wondering because 'it works' like a charm on the provided sample and on winxp).

Posted: Thu Jun 21, 2007 8:24 pm
by Trond
Psychophanta wrote:Different heaps?
Isn't supposed that dll and exe point to the same address to get and/or set data on it?
Sure, but heaps in Windows are created with HeapCreate() and different heaps are created in a shared memory space for the exe and dll.

Posted: Thu Jun 21, 2007 8:25 pm
by Trond
Flype wrote:@freak, and all.

thanks a lot for clarifying this behaviour.


i have still a short one :

why 'env() = *env' is compiled without error if this is forbidden ?
what's the use... it's pretty dangerous to let guys like us to allow playing forbidden games :D
a debugger warning, or compiler error might be added.
It's appears to be legal but it surely will cause you tons of problems.

Edit: Like, in real life it's not illegal to cut off your arm, but often you'll find yourself lacking an arm afterwards.