Page 1 of 1
get data from DLL
Posted: Sun Apr 25, 2021 2:45 am
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
Re: get data from DLL
Posted: Sun Apr 25, 2021 9:10 am
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.
Re: get data from DLL
Posted: Sun Apr 25, 2021 12:16 pm
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
Re: get data from DLL
Posted: Sun Apr 25, 2021 4:44 pm
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 ...
Re: get data from DLL
Posted: Sun Apr 25, 2021 5:02 pm
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
Re: get data from DLL
Posted: Sun Apr 25, 2021 5:29 pm
by Mijikai
PureBasic produces a *.lib file alongside the DLL for you so there is no reason to use OpenLibrary().
Re: get data from DLL
Posted: Sun Apr 25, 2021 10:26 pm
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.
Re: get data from DLL
Posted: Mon Apr 26, 2021 6:34 am
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
Re: get data from DLL
Posted: Mon Apr 26, 2021 1:02 pm
by dempdeezzpp
I am very glad that this topic is developing, although I just wanted to understand the logic)
Pardon my bad english
Re: get data from DLL
Posted: Mon Apr 26, 2021 8:59 pm
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.
Re: get data from DLL
Posted: Mon Apr 26, 2021 10:23 pm
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.