Sign in to follow this  
Followers 0
Sundance

using DLL handle within another script

12 posts in this topic

#1 ·  Posted (edited)

Hi all,
 
after some month it's time for another problem that arises bevore my eyes...
 
I try to explain it in short sentences:
 
 
Script1 (S1) opens a DLL and call some functions inside it. Then S1 executes another Script (S2).

S1 writes the DllOpen handle into a INI file.

S2 now also needs to call some functions inside the same DLL using the same handle S1 got when
calling OpenDLL.
 
Problem: The DllCall within S2 fails with @error = 1  => unable to use the DLL file.
 

It seems that S2 can't use the handle created from S1.
 
I tried to start S2 from S1 with the help of _WinApi_CreateProcess and setting the $fInherit flag to true but it won't help.

 

Local $tProcess = DllStructCreate($tagPROCESS_INFORMATION)
Local $tStartup = DllStructCreate($tagSTARTUPINFO)

DllStructSetData($tStartup, "Size", DllStructGetSize($tStartup))

_
WinAPI_CreateProcess("", '"' & @ScriptDir & 'Some.exe" ' & $sParameters, 0, 0, True, 0, 0, "", DllStructGetPtr($tStartup), DllStructGetPtr($tProcess))

 

In C languages it is possible to use handles given from other (parent) executables. So in AutoIt it surely is also possible but i haven't found the place where to dig...

Has someone a little hint for me?

 

thanks in advance

Sundance

 

 

 







Edited by Sundance

Share this post


Link to post
Share on other sites



Why do you think you need to pass a dll handle in the first place?

Don't confuse a Dll handle and a file handle (which indeed can be passed to children).


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Hi John,

thanks for a reply. The whole source code is to long to post and the problem is only a fragment of it. I surely could create a testscript but i thougth that someone knows if its possible to make a DllCall from script Y which where called by script X which already has opened the Dll. So its best to forget the lines of code i posted. Here are to scripts which show what i mean.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.8.0
 Author:         myName

 Script Function:
 Template AutoIt script.

#ce ----------------------------------------------------------------------------
#include <WinApi.au3>
#include "_DLLFunctions.au3"
; Script Start - Add your code below here

Local $hDll = DllOpen("user32.dll")
Local $sINIread
Local $hLibraryHandle = _DLL_GetLoadedLibraryHandle("user32.dll")
_DLL_ForcePermanentLoad("user32.dll")

Local $tProcess = DllStructCreate($tagPROCESS_INFORMATION)
Local $tStartup = DllStructCreate($tagSTARTUPINFO)

DllStructSetData($tStartup, "Size", DllStructGetSize($tStartup))

; delete old INIfile
If FileExists(@ScriptDir & "\dlltest.ini") Then
 FileDelete(@ScriptDir & "\dlltest.ini")
EndIf

; writing the DLL handle to the INI so script2 can read the handle
IniWrite(@ScriptDir & "\dlltest.ini", "COMMON", "HANDLE", $hLibraryHandle)

; consoleoutput
ConsoleWrite(@CRLF & "--------------------------------------------------------------------------------" & @CRLF)
ConsoleWrite(@ScriptName & ": handle from DllOpen         : " & $hDll & @CRLF)
ConsoleWrite(@ScriptName & ": handle from getLoadedLibrary: " & $hLibraryHandle & @CRLF)

$bResult = _WinAPI_CreateProcess("", '"' & @ScriptDir & '\script2.exe"', 0, 0, True, 0, 0, "", DllStructGetPtr($tStartup), DllStructGetPtr($tProcess))

If Not $bResult Then
 ConsoleWrite(@ScriptName & ": " & "error creating process script2.exe!  Exiting..." & @CRLF)
 Exit
EndIf

ConsoleWrite(@ScriptName & ": " & "created process script2.exe" & @CRLF)

$sINIread = "error"

While $sINIread = "error"
 $sINIread = IniRead(@ScriptDir & "\dlltest.ini", "COMMON", "EXITED","error")
 Sleep(500)
WEnd

ConsoleWrite(@CRLF & "--------------------------------------------------------------------------------" & @CRLF)
ConsoleWrite(@CRLF)

DllClose($hDll)
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.8.0
 Author:         myName

 Script Function:
 Template AutoIt script.

#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here

Local $result
Local $hDll = IniRead(@ScriptDir & "\dlltest.ini", "COMMON", "HANDLE", "error")

If $hDll = "error" Then
 ConsoleWrite(@ScriptName & ": error reading Dll handle from INI file. Exiting..." & @CRLF)
Else
 ConsoleWrite(@CRLF & @ScriptName & ": read handle value from INI: " & $hDll & @CRLF)
EndIf

; now call the DLL

$result = DllCall($hDll , "int", "MessageBox", "hwnd", 0, "str", "DllCall", "str", "using parent Dll handle", "int", 0)

ConsoleWrite(@CRLF & @ScriptName & ": " & "DllCall finished with @error value of " & @error & @CRLF & @CRLF)

IniWrite(@ScriptDir & "\dlltest.ini", "COMMON", "EXITED","finished")

Exit

Put both scripts in a directory, compile script2 and run script1.  Hope that explains it better.

@jchd: I don't need a file handle its really a Dll handle :-)

EDIT: 22.10: added Ascend4nt's Dll functions au3.

 

The Dlls are part of a bigger project and programmed by someone else. But i see the problem is not an easyy one. Will also further think about a possible solution...

 

thanks guys

Sundance

Edited by Sundance

Share this post


Link to post
Share on other sites

Did you check the value of the dll "handle" written to the ini file? I think the quotation marks are there for a reason in the help-file article for dllopen(). I'm not quite sure, but I think the dll-handle stuff is done in the background and not really user accessible in AutoIt, maybe worth a question in the Dev-Chat :)?

Share this post


Link to post
Share on other sites

Hi KaFu,

i tried it with INT($hDll) and creating a Dll structure using it within the DllCall but the error stays the same. I will use those two scripts to try it again. If i can't find a solution i will go to the Dev-Chat. The only thing i know is that our programmer who wrote the DLLs says in C++ it no prob.

I will report back.

Thanks guys.

Sundance

PS: if someone can bring some light into it i still would be happy :-) 

Share this post


Link to post
Share on other sites

Fire your programmer then.

Dll is loaded in memory space of the process. Two different processes have two separated memory spaces. One process can't use dll-s of the other process, it has to load them for itself. That's the whole point of dlls.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

AutoIt hides the real DLL handle. DllOpen just returnes an integer to work with. Sometimes it would be nice, when AutoIt does not hide things from you. Same thing with FileOpen.


Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Hi trance,

your statement was also my opinion . Can be that the programmer doesn't know the limitations of AutoIt (threads, multitasking,...). I took a look at Ascend4nt's  Process_Create_Thread functions but i think that won't do the trick. Ascend4nt uses a binary string as a representation of code. I would need to convert a au3 script into this binary representation (au3->exe->string). I know there is a possibility of running an au3 script as a string representation. I did that ~3 years ago. I will take a look and see if i can use this in combination with Ascend4nt's Thread functions.

Edited by Sundance

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Just a short info funkey. You can use Ascend4nt's Dllfunctions au3 to get the handle of a opened DLL.

But using the 'real' Dll handle obviously won't bring me any further. Digging more... :-)

Edited by Sundance

Share this post


Link to post
Share on other sites

Perhaps if you outlined your endgame, some suggestions might arise.

At the moment, only info is that you want/need to do this.

If it's not a secret, can you explain why you want to do this?

I'm struggling to think of one.


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

The problem is that we need to call the DLL several times with a function in it which calls a CallBack function in the au3 file. The DllCall won't return and continuously calls the CallBack function so that the CallBack function can write infos to some INI files. So we need to make this DllCall from outside the main script cause the main script needs to run further. Like calling a Run command ...

Our programmer says that its essential that the DLL only will be called once. Seems he creates some data structures within the DLL. I think i need to ask him how we can prevent that issue.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0