get data from DLL

Just starting out? Need help? Post your questions and find answers here.
dempdeezzpp
User
User
Posts: 11
Joined: Wed Feb 03, 2021 12:04 am

get data from DLL

Post by dempdeezzpp »

I need help getting data from dll. not how not to set up a mugu. I searched the forum and there are no results either (
I have yet to show such an example, but mine has the same meaning. This is the first time I come across this, an experienced one will immediately understand. NOT an option to use temporary file.
Tnx

Code: Select all

; DLL FILE
CompilerSelect #PB_Compiler_OS
   CompilerCase #PB_OS_Windows
      #sep$ = "\"
    CompilerCase #PB_OS_Linux
      #sep$ = "/"
CompilerEndSelect
Procedure __FileSearch2(sPath.s, List Files.s(), RID) 
  Protected sName.s, c = 0
  Protected Dim aExaDir(125)
  Protected Dim aSePath.s(125)
  aSePath(c) = sPath
  aExaDir(c) = ExamineDirectory(#PB_Any, sPath, "*")
  If Not aExaDir(c)
    ProcedureReturn 0
  EndIf
  Repeat
    While NextDirectoryEntry(aExaDir(c))
      sName=DirectoryEntryName(aExaDir(c))
      If sName = "." Or sName = ".."
        Continue
      EndIf
      If DirectoryEntryType(aExaDir(c)) = #PB_DirectoryEntry_Directory
        sPath = aSePath(c)
        c + 1
        aSePath(c) = sPath + sName + #sep$
        aExaDir(c) = ExamineDirectory(#PB_Any, aSePath(c), "*")
        If Not aExaDir(c)
          c - 1
        EndIf
      Else
        If MatchRegularExpression(RID, sName) And AddElement(Files())
          Files() = aSePath(c) + sName
        EndIf
      EndIf
    Wend
    FinishDirectory(aExaDir(c))
    c - 1
  Until c < 0
EndProcedure


ProcedureDLL.s _FileSearch(*Result.string, Path$, Mask$ = ".+?")
  Protected RID, Len, Res, *Point
  NewList Files.s()
  RID = CreateRegularExpression(#PB_Any, Mask$)
  If RID
    If  Right(Path$, 1) <> #sep$
      Path$ + #sep$
    EndIf
    If __FileSearch2(Path$, Files.s(), RID)
      FreeRegularExpression(RID)
    EndIf
  Else
    ProcedureReturn
    Debug RegularExpressionError()
  EndIf
  Len=0
  ForEach Files()
    Len + Len(Files())+2
  Next 
  *Result\s = Space(Len)
  *Point = @*Result\s
  ForEach Files()
    CopyMemoryString(Files()+#CRLF$, @*Point)
  Next
  ClearList(Files()) 
EndProcedure

Code: Select all

Define StartTime=ElapsedMilliseconds()
Define Path$ = "C:\Users\37258\Desktop\Codes" ; <<<- DIRECTORY
Define Result.string
_FileSearch(@Result, Path$, "\A.*?\.pb\z")
Debug Result\s
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: get data from DLL

Post by Mijikai »

The dll and exe have different scopes so only one of them should handle memory.

Example code:

Code: Select all


EnableExplicit

Structure FILES_STRUCT;<- in dll & exe
  List file.s()
EndStructure

ProcedureDLL.i FileSearch();<- in dll
  Protected *files.FILES_STRUCT
  Protected index.i
  *files = AllocateStructure(FILES_STRUCT)
  If *files
    For index = 0 To 127
      If AddElement(*files\file())
        *files\file() = "dummy" + Str(index) + ".bin"
      Else
        FreeStructure(*files)
        ProcedureReturn #Null
      EndIf
    Next
    ProcedureReturn *files
  EndIf
  ProcedureReturn #Null
EndProcedure

ProcedureDLL.i FileSearchRelease(*Files);<- in dll
  FreeStructure(*Files)
  ProcedureReturn #Null
EndProcedure

Procedure.i Main();<- in exe
  Protected *files.FILES_STRUCT
  *files = FileSearch()
  If *files
    ForEach *files\file()
      Debug *files\file()
    Next
    FileSearchRelease(*files)
  EndIf
  ProcedureReturn #Null
EndProcedure

Main()

End
Also CopyMemoryString() in your src will always override the same address.
Either update the write pointer (ex. with the last parameter) or omit the write pointer in order to append further data.
Olli
Addict
Addict
Posts: 1200
Joined: Wed May 27, 2020 12:26 pm

Re: get data from DLL

Post by Olli »

(not tested)

Code: Select all


Structure Buffer
 Array A$(1)
 StandBy.I
 ShutDown.I
 Done.I
 Progress.D
EndStructure


Declare Client(*This.Buffer) ; to be commented

Procedure Server()
 Define *Buffer.Buffer
 AllocateStructure(*Buffer, Buffer)
 
 CreateThread(@Client(), *Buffer) ; @Client() to be replaced with FunctionAddress()
 
 Repeat
  Delay(200)
  *Buffer\StandBy = 1
  Debug Str(Int(*Buffer\Progress * 100) ) + "%"
  *Buffer\StandBy = 0
 Until *Buffer\Done
 
 For I = 0 To (ArraySize(*Buffer\A$() ) - 1)
  Debug *Buffer\A$(I)
 Next
 
 FreeStructure(*Buffer)
EndProcedure

Server()






; DLL dependancy

CompilerIf 0 ; set to 1 on DLL compiling

Structure Buffer
 Array A$(1)
 StandBy.I
 ShutDown.I
EndStructure

CompilerEndIf


Procedure Client(*This.Buffer)

 With *This
  Redim \A$(63)
  For I = 0 To 63
  
   While \StandBy And Not \ShutDown
    Delay(16)
   Wend
    
   If \ShutDown
    ProcedureReturn
   EndIf
  
   \A$(I) = "#" + Str(I)
   \Progress = I / 63
   
  Next
  \Done = 1
 EndWith
EndProcedure
dempdeezzpp
User
User
Posts: 11
Joined: Wed Feb 03, 2021 12:04 am

Re: get data from DLL

Post by dempdeezzpp »

Thank you! The server option does not work, I modified the first option, otherwise it swears) It looks like this:

Code: Select all

;------------------------------------------------------------------------------------------------------------------------
; EXE:
; PureBasic 5.72 х64   =(NOT UTF8 file Format!!! < Not work)
; Windows 10
; Endry(DeMpDeez)
; Thanks to Mijikai

EnableExplicit

Structure ListOfNames 
  ReturnedNames.s
EndStructure 

PrototypeC MyProc(*ID.ListOfNames) 
Global MyProc.MyProc 

If OpenLibrary(0,"dll.dll")
  MyProc = GetFunction(0,"MyProc") 
EndIf   

Global ID.ListOfNames

Procedure load() 
  MyProc(@ID)
  Debug ID\ReturnedNames
EndProcedure 

load()

CloseLibrary(0)
End
;------------------------------------------------------------------------------------------------------------------------
; DLL:

EnableExplicit

Structure ListOfNames 
  ReturnListOfNames.s
EndStructure 

Global Result.ListOfNames 

ProcedureDLL.l MyProc(*ID.ListOfNames)
  Result\ReturnListOfNames = "47567777567845675467456856786748678"+Chr(013)+"47567777567845675467456856786748678"+Chr(013)+"47567777567845675467456856786748678"+Chr(013)+"47567777567845675467456856786748678"+Chr(013)+"47567777567845675467456856786748678"+Chr(013)+"47567777567845675467456856786748678"+Chr(013)+"47567777567845675467456856786748678"+Chr(013)+"47567777567845675467456856786748678"
  *ID\ReturnListOfNames = Result\ReturnListOfNames 
EndProcedure
Can be used by anyone)
The question is settled ...
dempdeezzpp
User
User
Posts: 11
Joined: Wed Feb 03, 2021 12:04 am

Re: get data from DLL

Post by dempdeezzpp »

+++++ I'll add an insetr array from Dll +++++++++++

Code: Select all

;------------------------------------------------------------------------------------------------------------------------
; EXE:
; PureBasic 5.72 х64   =(NOT UTF8 file Format!!! < Not work)
; Windows 10
; Endry(DeMpDeez)

EnableExplicit

Structure Array
  item.s[0]
EndStructure

Global Sise.i = 10  ; Array size.
Global i=0
Global *var.Array

If OpenLibrary(0,"Dll.dll")
  *var.Array=CallFunction(0,"CreateArray", Sise)
  For i=0 To 5 ; Insert only 5 items.
    MessageRequester("hi",*var.Array\item[i])
  Next
  CloseLibrary(0)
EndIf


;------------------------------------------------------------------------------------------------------------------------
;DLL:
ProcedureDLL AttachProcess(num.i)
 Global Dim Array.s(num)
EndProcedure
ProcedureDLL.l CreateArray(num.i)
  AttachProcess(num)
  For i=0 To num
    Array(i)="Line of "+Str(i)
  Next
  ProcedureReturn @Array()
EndProcedure
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: get data from DLL

Post by Mijikai »

PureBasic produces a *.lib file alongside the DLL for you so there is no reason to use OpenLibrary().
Olli
Addict
Addict
Posts: 1200
Joined: Wed May 27, 2020 12:26 pm

Re: get data from DLL

Post by Olli »

@Mijikai

I have never known how to use a LIB file. Could you adapt the last code of dempdeezzpp?

@dempdeezzpp

I apologize : I made it without computer... My error is in the syntax of AllocateStructure which is in fact like this :

Code: Select all

*This.SomeOne = AllocateStructure(SomeOne)
But without the code of Mijikai, I would do nothing : I did not really initially understand the question !
I was imagining you wanted to prevent a virus from read the datas exchanged, and thank a encryption was necessary.
Too complex : your source code is good, simple.
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: get data from DLL

Post by Mijikai »

Olli wrote: Sun Apr 25, 2021 10:26 pm I have never known how to use a LIB file. Could you adapt the last code of dempdeezzpp?
...
Would look like this.

Exe:

Code: Select all

EnableExplicit

Structure LIST_OF_NAMES_STRUCT 
  ReturnedNames.s
EndStructure

Import "test_dll.lib";<- all that is needed :)
  MyProc.i(*ID.Integer)
EndImport

Procedure.i Main()
  Protected *id.LIST_OF_NAMES_STRUCT
  Debug MyProc(@*id)
  Debug *id\ReturnedNames
  ProcedureReturn #Null
EndProcedure

Main()

End
Dll:

Code: Select all

EnableExplicit

Structure LIST_OF_NAMES_STRUCT 
  ReturnedNames.s
EndStructure

Global Result.LIST_OF_NAMES_STRUCT 

ProcedureDLL.i MyProc(*ID.Integer);<- since the code should run on x64 i changed the return type to .i
  If *ID
    Result\ReturnedNames = "47567777567845675467456856786748678" + #CR$ + 
                           "47567777567845675467456856786748678" + #CR$ + 
                           "47567777567845675467456856786748678" + #CR$ +
                           "47567777567845675467456856786748678" + #CR$ + 
                           "47567777567845675467456856786748678" + #CR$ + 
                           "47567777567845675467456856786748678" + #CR$ + 
                           "47567777567845675467456856786748678" + #CR$ + 
                           "47567777567845675467456856786748678"
    *ID\i = @Result
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure
dempdeezzpp
User
User
Posts: 11
Joined: Wed Feb 03, 2021 12:04 am

Re: get data from DLL

Post by dempdeezzpp »

I am very glad that this topic is developing, although I just wanted to understand the logic)
Pardon my bad english
Olli
Addict
Addict
Posts: 1200
Joined: Wed May 27, 2020 12:26 pm

Re: get data from DLL

Post by Olli »

Thank you Mijikai for this example. I just do a remark about the global variable : in the way of a thread, I am not sure this use is valid.

I would prefer the memory dynamically allocated instead of global strings.

Code: Select all

; in the "client" function or thread
*Result = AllocateMemory(StringByteLength(A$ + "Z") ; "Z" is an artefact to consider the null terminal character.
PokeS(*Result, A$)

Code: Select all

; in the "server" function
Result$ = PeekS(*ReturnedString)
; Here is a facultative option...
; Erase the datas
For I = 0 to MemorySize(*ReturnedString)
 PokeA(*ReturnString + I, 48)
Next
: end of the facultative option !
FreeMemory(*ReturnedString)
But for the demonstration, the compactness of your code, Mijikai, congratulations.
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: get data from DLL

Post by Mijikai »

Olli wrote: Mon Apr 26, 2021 8:59 pm I would prefer the memory dynamically allocated instead of global strings...
I fully agree, that is also what i suggested in my original reply.
In my last example i only followed your request but accidentally adapted the wrong code, the global string one instead of the array one - my bad.
I wont say that the global string variant is bad but it is certainly a limiting and very error prone solution.
Post Reply