Jump to content
Sign in to follow this  
argumentum

[SOLVED] to DLLopen or not ( as in "to be or not to be")

Recommended Posts

From the manual: "DllOpenOpens a DLL file for use in DllCall." But I see everywhere in the distribution UDFs, no use of it for DllCall().

In the manual, the example is:

Local $hDLL = DllOpen("user32.dll")
DllCall($hDLL, "int", "MessageBox", "hwnd", 0, "str", "Some text", "str", "Some title", "int", 0)
DllClose($hDLL)

but what I actually see is the UDFs, is more along the lines of:

; Calling the MessageBox API directly.
DllCall("user32.dll", "int", "MessageBox", _
        "hwnd", 0, _ ; Handle to the parent window
        "str", "Some text", _ ; The text of the message box
        "str", "Some title", _ ; The title of the message box
        "int", 0) ; Flags for the message box.


So, "to DllOpen or not to DllOpen, that is the question."

Edited by argumentum

Share this post


Link to post
Share on other sites

It's a bit like FileWrite, where you can use the filename or a handle you open with FileOpen beforehand. If your call is a one-off then it's overkill to get a handle for it, call it, then close it again. But if you're going to be accessing the dll dozens or hundreds (millions?) of times in your code, it's faster to get a handle once and use that while you need the dll, then close it once.^_^ And of course, the UDFs are mostly single call affairs (GDI+ is an exception), so the only way to ensure the handle gets closed (no memory leak) is to open and close it directly per UDF call.

Edited by RTFC

Share this post


Link to post
Share on other sites
2 minutes ago, RTFC said:

if you're going to be accessing the dll dozens or hundreds (millions?) of times

..yes, I see no time difference between one way or the other.
I the DllCall remark is : If a dll filename is given then the DLL is automatically loaded and then closed at the end of the call. If you want to manually control the loading and unloading of the DLL then you should use DllOpen() and DllClose() and use a handle instead of a filename in this function.

I came to this question while looking at <Date.au3> and the question popped into my head: why is this not with a handle to "kernel32.dll" as is constantly called. =/

Share this post


Link to post
Share on other sites

1) The dll itself may already be in virtual memory due to earlier calls (and you'd probably need heavy-duty benchmarking to perceive a notable difference anyhow)

2) avoid memory leaks due to dangling handles

Edited by RTFC

Share this post


Link to post
Share on other sites
25 minutes ago, RTFC said:

1) The dll itself may already be in virtual memory due to earlier calls

So AutoIt loads the DLL when first called, and closes it when the program/script closes ?

Maybe system DLLs ( those in use since Win95 ) are accounted for within AutoIt but otherwise it'd be good to Open and close manually ?

Or there are types of DLLs, like those used for GDI+, that need the Open/Close functionality due to the "type" of DLL, and I say "type" with quote marks because, I don't know much, other than to script ( somewhat ) if there is a UDF already in place :)

Edited by argumentum
clarify

Share this post


Link to post
Share on other sites

you missed the more important #2. He suggests closing handles you open. This is the best practice, now and forever, you can sing that like at church.....

in unmanaged  code, you had darned well better clean up after yourself. With .NET managed stuff, it does the garbage cleanup for you, but if you are allocating memory and resources, you should free it when you exit or don't need it anymore

 

https://www.autoitscript.com/autoit3/docs/functions/DllClose.htm

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Share this post


Link to post
Share on other sites
14 minutes ago, Earthshine said:

you missed the more important #2. He suggests closing handles you open

AutoIt closes those DLLs ( on exit or right after the call, no clue yet ), BUT there are those that need to be handled manually like GDI or Richedit. My question is when and why use DllOpen() or when is just impractical.
 

16 minutes ago, Earthshine said:

in unmanaged  code, you had darned well better clean up after yourself

I know that I should always clean after myself. My mother told me that, and my father reinforced the knowledge with his slipper shoes :P 

Share this post


Link to post
Share on other sites
11 minutes ago, argumentum said:

My question is when and why use DllOpen() or when is just impractical.

Thought that question was answered already by @RTFC. When you use DllCall() with a filename, AutoIt3 will perform DllOpen();DllCall();DllCLose() for you.
This is fine when doing a single DllCall, but when you want to do a thousand DllCall as fast as possible you can imagine it is faster to one DllOpen() at the beginning, then do all the DllCall's using the openen filehandle and then close it.....   right?

Same counts for FileRead/FileWrite operations.

Jos

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites
10 minutes ago, Jos said:

but when you want to do a thousand DllCall as fast as possible you can imagine it is faster to one DllOpen()

well, not that noticeable:

Global $kernel32dll = DllOpen("kernel32.dll")
OnAutoItExitRegister("closeDlls")
Func closeDlls()
    DllClose($kernel32dll)
EndFunc   ;==>closeDlls
Local $times[4][2000]
$count = 1
$times[0][0] = 0
$lastcount = -9
$tt = TimerInit()
While $count < 2000
    $times[0][$count] = TimerDiff($tt)
    $times[1][$count] = _MSec()             ; AutoIt Open/Close DLL
;~  $times[1][$count] = _MSec($kernel32dll) ; managed Open/Close DLL
    $times[2][$count] = @error
    $times[3][$count] = @extended
    If $times[0][$count] <> $times[0][$count - 1] Then $count += 1
WEnd
For $i = 1 To $count - 1
    If $times[1][$i] = $times[1][$i - 1] Then ContinueLoop
    ConsoleWrite('TimerDiff, ' & $i & ' @MSEC = ' & StringFormat("%5.5f, %d", $times[0][$i], $times[1][$i]) & " - " & $times[2][$i] & "," & $times[3][$i] & @CRLF) ;### Debug Console
Next
ConsoleWrite('TimerDiff, ' & $count - 1 & ' @MSEC = ' & StringFormat("%5.5f, %d", $times[0][$count - 1], $times[1][$count - 1]) & @CRLF) ;### Debug Console
Exit

Func _MSec($kernel32dll = "kernel32.dll")
    Local $stSystemTime = DllStructCreate("ushort varYear;ushort varMon;ushort varDofW;ushort varDay;ushort varHour;ushort varMin;ushort varSec;ushort varMsec")
    DllCall($kernel32dll, 'none', 'GetSystemTime', 'ptr', DllStructGetPtr($stSystemTime)) ; UTC time
    Return SetError(@error, @extended, StringFormat('%03d', DllStructGetData($stSystemTime, 8)))
EndFunc   ;==>_MSec

that is why I'm posting the question.   

Share this post


Link to post
Share on other sites
1 hour ago, Jos said:

then do as you please

Don't get me wrong. There is a difference of some porcentage* and yes, it is faster to do the DllOpen. The question is a bit deeper. The <Date.au3> does not use DllOpen()  - I was looking at that when my question popped up - and it, in my view, should use it, then again, is impractical for a call or 2 the user would make, to handle the "IsItLoaded" and when to close it. So I was looking for a deeper explanation to, when and why, other than "you can go either way, just clean house once you're done". There are those DLLs that must be properly handled or the script will crash. There must be a reason.

That is all.

* PS: I added this later for anyone that in the future would like to see how much faster, tho, this should not be about speed alone.

Spoiler
Global $stSystemTime = DllStructCreate("ushort varYear;ushort varMon;ushort varDofW;ushort varDay;ushort varHour;ushort varMin;ushort varSec;ushort varMsec")
Global $kernel32dll = DllOpen("kernel32.dll")
OnAutoItExitRegister("closeDlls")
Func closeDlls()
    DllClose($kernel32dll)
EndFunc   ;==>closeDlls
Local $nLoopCount = 10000 ; <--- change this if you feel like it
Local $nTestCount = 10    ; <--- change this if you feel like it
Local $times[4][$nLoopCount]
Local $av[$nTestCount][2]
$av[0][0] = UBound($av) - 1
For $n = 1 To $av[0][0]

    $tt = TimerInit()
    For $count = 1 To $nLoopCount - 1
        $times[0][$count] = TimerDiff($tt)
        $times[1][$count] = _MSec() ; AutoIt Open/Close DLL
    Next
    $av[$n][0] = Round($times[0][$nLoopCount - 1])
    ConsoleWrite('AutoIt Open/Close DLL = TimerDiff, ' & $av[$n][0] & " .ms" & @TAB) ;### Debug Console

    $tt = TimerInit()
    For $count = 1 To $nLoopCount - 1
        $times[0][$count] = TimerDiff($tt)
        $times[1][$count] = _MSec($kernel32dll) ; managed Open/Close DLL
    Next
    $av[$n][1] = Round($times[0][$nLoopCount - 1])
    ConsoleWrite('managed Open/Close DLL = TimerDiff, ' & $av[$n][1] & " .ms ( " & Round((1 - ($av[$n][1] / $av[$n][0])) * 100) & " % faster )" & @CRLF) ;### Debug Console
Next
Exit

Func _MSec($kernel32dll = "kernel32.dll")
    DllCall($kernel32dll, 'none', 'GetSystemTime', 'ptr', DllStructGetPtr($stSystemTime)) ; UTC time
    Return SetError(@error, @extended, StringFormat('%03d', DllStructGetData($stSystemTime, 8)))
EndFunc   ;==>_MSec

 

 

Edited by argumentum
added test bed

Share this post


Link to post
Share on other sites
31 minutes ago, argumentum said:

AutoIt closes those DLLs ( on exit or right after the call

If called with the filename, the dll is closed immediately after the call; if called with the earlier obtained handle it stays open until closed by the user or AFAIK upon normal script termination (although this is sloppy practice ,and you shouldn't rely on it). However, in case of abnormal termination/crash, you may have a memory leak.

34 minutes ago, argumentum said:

there are those that need to be handled manually like GDI

I would suggest you call the GDI Startup function (because there are version-specific settings involved) rather than opening that dll directly. But in general, any dll can be opened and closed on a call-by-call basis using the filename or user-opened and closed separately. Regarding filename-based calls in the standard includes such as <Date.au3>, remember that these UDFs are meant to function on their own, without users needing to be aware of handles to be obtained first or closed after. So by sacrificing a little processing speed, calling a dll function can be made a single action, which makes the task much easier for beginners, and more empowering.:)

58 minutes ago, argumentum said:

my father reinforced the knowledge with his slipper shoes

:blink: Well, I guess you'll have to be thankful he didn't have mountaineering boots with ice crampons close to hand.:D

Share this post


Link to post
Share on other sites

Think mega thousands of calls. It makes a diff. Everyone starts as a beginner but you can’t be a beginner forever you need to learn how to program correctly

Many many years ago I read a book called writing structured basic and it changed my life

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Share this post


Link to post
Share on other sites
27 minutes ago, Earthshine said:

Many many years ago I read a book called writing structured basic

I started with basic on an Apple II back in 1984. After that I studied microprocessors (1985), Then quit, whent fix planes.
then years later started with TPascal 5.5. I have an idea. Picked up coding back in 2005 looked at Delphi ...but i found AutoIt.
I should have opened this topic in a chat forum but I did it here. Is not help I wanted, but educated views on why, how, etc.
@RTFC answered the question. Repeatedly. 
I was looking for ... go figure, clarification on why the UDF was written as such.
Thank you @Earthshine for your participation.
And since i'm in a thank you letter, thanks @Jos for your input, I added a piece of code to show the speed gain ( %5 on average in my test PC ).
I'm happy :)

Share this post


Link to post
Share on other sites
9 hours ago, argumentum said:

Is not help I wanted, but educated views on why, how, etc.

I never had you pegged as a beginner, argumentum, and I reckon you posed an interesting, valid question (definitely not mere chat). Investigating and questioning(!) the source code is a good way of gaining a deeper understanding; I try to get a peek under the hood myself when I get the chance. So don't put yourself down, okay?:)

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By corz
      This is a magnifier-color-picker thing mostly based on some code I found on Stack Overflow, of all places. At least all the clever bits are from there. 
      I'd love to use this code inside an app I'm working on. But it has an issue. The first time the mag pops up it works perfectly, but the second and subsequent times, it's a boring grey square. 
      One of you smart dudes will probably look at this and go, "Aha!", but I'm stumped.
      #include <WindowsConstants.au3> #include <WinAPI.au3> #include <StaticConstants.au3> MagWindow() MagWindow() ; Magnifier-Color-Picker.. ; Props to McBarby for the cross-hairs. func MagWindow() global $iMagZoom = 5 global $iMagWidth = Ceiling(100/$iMagZoom) global $iMagHeight = Ceiling(100/$iMagZoom) global $hDCDesk, $hDCZoom, $hPen global $hUser32 = DllOpen("user32.dll") global $hGDI32 = DllOpen("gdi32.dll") global $pixel_color, $mag_open = false local $mX, $mY global $hCross = GUICreate('', 48, 48, -1, -1, $WS_POPUP, $WS_EX_TOPMOST) WinSetTrans($hCross, '', 0) GUISetCursor(3, 1, $hCross) global $hZoom = GUICreate("MagPicker", $iMagWidth * $iMagZoom, $iMagHeight * $iMagZoom, _ MouseGetPos(0), MouseGetPos(1), $WS_POPUP+$WS_BORDER, $WS_EX_TOPMOST) global $mag_label = GUICtrlCreateLabel("placehold", (($iMagHeight * $iMagZoom)/2)+2, ($iMagHeight * $iMagZoom) - 13, _ (($iMagHeight * $iMagZoom)/2)-3, 12, $SS_RIGHT) ; put this after the GUICreate()s so that it will not error on startup with mouse already moving. (now trapped! but we will leave them here.) global $__hMouseProc = DllCallbackRegister("_MouseProc", "long", "int;wparam;lparam") global $__hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($__hMouseProc), _WinAPI_GetModuleHandle(0)) GUISetState(@SW_SHOW, $hCross) GUISetState(@SW_SHOW, $hZoom) $mag_open = true ; once at start, then from the mouse-callback-function.. _Magnify() while $mag_open Sleep(50) $mX = MouseGetPos(0) $mY = MouseGetPos(1) $pixel_color = Hex(PixelGetColor($mX, $mY), 6) GUICtrlSetData ($mag_label, $pixel_color) wend GUIDelete($hZoom) GUIDelete($hCross) ReleaseHooks() endfunc func _Magnify($_iX=-1, $_iY=-1) local Static $fInit = true if $fInit then $fInit = False $hDCDesk = (DLLCall($hUser32, "int", "GetDC", "hwnd", 0))[0] $hDCZoom = (DLLCall($hUser32, "int", "GetDC", "hwnd", $hZoom))[0] $hPen = (DLLCall($hGDI32, "int", "CreatePen", "int", 0, "int", 3, "int", 0x008b9094))[0] ; 0=PS_SOLID, dark-blue (0x00BBGGRR) DLLCall($hGDI32, "int", "SelectObject", "int", $hDCZoom, "hwnd", $hPen) $_iX = MouseGetPos(0) $_iY = MouseGetPos(1) endif local $iW = $iMagWidth * $iMagZoom, $iH = $iMagHeight * $iMagZoom if not @error then DLLCall($hGDI32, "int", "StretchBlt", "int", $hDCZoom, "int", _ 0, "int", 0, "int", $iW, "int", $iH, "int", $hDCDesk, "int", _ $_iX - $iMagWidth/2, "int", $_iY - $iMagHeight/2, "int", $iMagWidth ,"int", $iMagHeight, _ "long", $SRCCOPY) ; draw the crosshair (start x, start y, end x, end y) _GDI32_DrawLine($hDCZoom, ($iW/2)-2, $iH/8, ($iW/2)-2, 4*($iH/8)-6, $hGDI32) ; vertical top _GDI32_DrawLine($hDCZoom, ($iW/2)-2, 5*($iH/8)-10, ($iW/2)-2, 7*($iH/8), $hGDI32) ; vertical bottom _GDI32_DrawLine($hDCZoom, $iW/8, ($iH/2)-2, (3*($iW/8))+6, ($iH/2)-2, $hGDI32) ; horizontal left _GDI32_DrawLine($hDCZoom, 4*($iW/8)+3, ($iH/2)-2, 7*($iW/8), ($iH/2)-2, $hGDI32) ; horizontal right endif endfunc func _GDI32_DrawLine(ByRef $_hDC, $_iX0, $i_Y0, $_iX1, $i_Y1, $_hDll=-1) If $_hDll = -1 then $_hDll = "gdi32.dll" Local $tCurrent = DllStructCreate("struct; long X;long Y; endstruct") DllCall($_hDll, "int", "MoveToEx", "int", $_hDC, "int", $_iX0, "int", $i_Y0, "ptr", DllStructGetPtr($tCurrent)) DllCall($_hDll, "int", "LineTo", "int", $_hDC, "int", $_iX1, "int", $i_Y1) return $tCurrent endfunc func _MouseProc($_nCode, $_wParam, $_lParam) local $tMSLLHOOKSTRUCT = DllStructCreate("struct; long X;long Y; endstruct; " & _ "DWORD mouseData; DWORD flags; DWORD time; ULONG_PTR dwExtraInfo;endstruct", $_lParam) if $_nCode < 0 Then Return _WinAPI_CallNextHookEx($__hHook, $_nCode, $_wParam, $_lParam) local $iX = $tMSLLHOOKSTRUCT.X, $iY = $tMSLLHOOKSTRUCT.Y switch $_wParam case $WM_LBUTTONDOWN CloseMag() case $WM_MOUSEMOVE if not $mag_open then return WinMove($hCross, "", $iX -24, $iY -24) Local $iXz = ($iX +24 + $iMagWidth*$iMagZoom > @DesktopWidth) ? $iX -(24 + $iMagWidth*$iMagZoom) : $iX +24 Local $iYz = ($iY +24 + $iMagHeight*$iMagZoom > @DesktopHeight) ? $iY -(24 + $iMagHeight*$iMagZoom) : $iY +24 WinMove($hZoom, "", $iXz + $iMagWidth/2, $iYz) _Magnify($iX, $iY) endswitch return _WinAPI_CallNextHookEx($__hHook, $_nCode, $_wParam, $_lParam) endfunc func ReleaseHooks() DLLCall($hUser32, "int", "ReleaseDC", "int", $hDCZoom, "hwnd", $hPen) DLLCall($hUser32, "int", "ReleaseDC", "int", $hDCDesk, "hwnd", 0) DLLCall($hUser32, "int", "ReleaseDC", "int", $hDCZoom, "hwnd", 0) DllClose($hUser32) DllClose($hGDI32) _WinAPI_UnhookWindowsHookEx($__hHook) DllCallbackFree($__hMouseProc) endfunc func CloseMag() ; called by mouse left click $mag_open = false endfunc  
      Thanks for any and all insights!
      ;o) Cor
    • By likehu
      Hello,
      I have compiled a reference DLL in VS 2015 Community and this  DLL works fine with project for which it is used. There is an interface from which u can access functions in DLL.
      Developers stated that this DLL is almost universal and can be used with any language with minor changes.
      I am trying to access its function from Autoit script and got an error 3, after calling DLLCall - "function" not found in the DLL file.
      Please have a quick look, I feel I miss something in C++ library with exporting functions and I do not know what to add as I am new to C++.
      Thank you.
      Source files and script also attached.
       
      Here is my script.
      Local $dll = DllOpen("C:\Users\Home\Desktop\dll\user.dll") ConsoleWrite("$dll handle = " & $dll & @CRLF) ;$dll handle = 1 Local $result = DllCall($dll, "double:cdecl", "ProcessQuery", "str", "dll$mynumber") If @error > 0 Then ConsoleWrite("Error: " & @error & @CRLF) ;Error = 3 If IsArray($result) Then ConsoleWrite("Array returned!" & @CRLF & "dll$mynumber: " & result[1]) Else ConsoleWrite("$result is not array. : " & $result & @CRLF) ;$result = 0 EndIf DllClose($dll) And here is dll source. As I understand, function "ProcessQuery" exported with help of DLL_IMPLEMENTS
      user.h
      //****************************************************************************** // // This file is part of the OpenHoldem project // Download page: http://code.google.com/p/openholdembot/ // Forums: http://www.maxinmontreal.com/forums/index.php // Licensed under GPL v3: http://www.gnu.org/licenses/gpl.html // //****************************************************************************** // // Purpose: Very simple user-DLL as a starting-point // // DO NOT CHANGE ANYTHING IN THIS FILE! // // This Header defines an interface // Functions and data-types must exactly match. // //****************************************************************************** #ifndef _INC_USER_H #define _INC_USER_H // Import and export directives // for use by this DLL and by OpenHoldem #ifdef USER_DLL #define DLL_IMPLEMENTS extern "C" __declspec(dllexport) #define EXE_IMPLEMENTS extern "C" __declspec(dllimport) #else #define DLL_IMPLEMENTS extern "C" __declspec(dllimport) #define EXE_IMPLEMENTS extern "C" __declspec(dllexport) #endif // Number of saved table-states // This number must not be changed, as we do a "& 0xFF" // at various places to normalize the index. const int kNumberOfHoldemStatesForDLL = 256; // SHoldemePlayer // used for sequence of 256 consequive table-states // !!!! Needs 2 more cards for Omaha, if not entirely removed struct holdem_player { char m_name[16] ; //player name if known double m_balance ; //player balance double m_currentbet ; //player current bet unsigned char m_cards[2] ; //player cards unsigned char m_name_known : 1 ; //0=no 1=yes unsigned char m_balance_known : 1 ; //0=no 1=yes unsigned char m_fillerbits : 6 ; //filler bits unsigned char m_fillerbyte ; //filler bytes }; struct holdem_state { char m_title[64] ; //table title double m_pot[10] ; //total in each pot unsigned char m_cards[5] ; //common cards unsigned char m_is_playing : 1 ; //0=sitting-out, 1=sitting-in unsigned char m_is_posting : 1 ; //0=autopost-off, 1=autopost-on unsigned char m_fillerbits : 6 ; //filler bits unsigned char m_fillerbyte ; //filler byte unsigned char m_dealer_chair ; //0-9 holdem_player m_player[10] ; //player records }; // Functions implemented and exported by the DLL, // imported by OpenHoldem DLL_IMPLEMENTS double __stdcall ProcessQuery(const char* pquery); DLL_IMPLEMENTS void __stdcall DLLOnLoad(); DLL_IMPLEMENTS void __stdcall DLLOnUnLoad(); // Functions implemented and exported by OpenHoldem, // imported by the DLL EXE_IMPLEMENTS double __stdcall GetSymbol(const char* name_of_single_symbol__not_expression); EXE_IMPLEMENTS void* __stdcall GetPrw1326(); EXE_IMPLEMENTS char* __stdcall GetHandnumber(); EXE_IMPLEMENTS void __stdcall ParseHandList(const char* name_of_list, const char* list_body); EXE_IMPLEMENTS char* __stdcall ScrapeTableMapRegion(char* p_region, int& p_returned_lengh); EXE_IMPLEMENTS void __stdcall SendChatMessage(const char *message); EXE_IMPLEMENTS void __stdcall WriteLog(char* format, ...); // Variables exported by OpenHoldem // avoiding the message-mess of WinHoldem, // no longer sending any state-messages // http://www.maxinmontreal.com/forums/viewtopic.php?f=174&t=18642 EXE_IMPLEMENTS extern holdem_state state[kNumberOfHoldemStatesForDLL]; EXE_IMPLEMENTS extern int state_index; #endif // _INC_USER_H  
      user.cpp    Here is dll$mynumber parameter.
      //****************************************************************************** // // This file is part of the OpenHoldem project // Download page: http://code.google.com/p/openholdembot/ // Forums: http://www.maxinmontreal.com/forums/index.php // Licensed under GPL v3: http://www.gnu.org/licenses/gpl.html // //****************************************************************************** // // Purpose: Very simple user-DLL as a starting-point // // Required OpenHoldem version: 7.7.6 // //****************************************************************************** // Needs to be defined here, before #include "user.h" // to generate proper export- and inport-definitions #define USER_DLL // #define OPT_DEMO_OUTPUT if you are a beginner // who wants to see some message-boxes with output of game-states, etc. // It is disabled upon request, // * as it is not really needed // * as some DLL-users don't have MFC (atlstr.h) installed // http://www.maxinmontreal.com/forums/viewtopic.php?f=156&t=16232 #undef OPT_DEMO_OUTPUT #include "user.h" #include <conio.h> #include <windows.h> #ifdef OPT_DEMO_OUTPUT #include <atlstr.h> #endif OPT_DEMO_OUTPUT // Supporting macros #define HIGH_NIBBLE(c) (((c)>>4)&0x0F) #define LOW_NIBBLE(c) ((c)&0x0F) // Card macro #define RANK(c) ( ISKNOWN(c) ? HIGH_NIBBLE(c) : 0 ) #define SUIT(c) ( ISKNOWN(c) ? LOW_NIBBLE(c) : 0 ) #define ISCARDBACK(c) ((c) == CARD_BACK) #define ISUNKNOWN(c) ((c) == CARD_UNDEFINED) #define ISNOCARD(c) ((c) == CARD_NOCARD) #define ISKNOWN(c) (!ISCARDBACK(c) && !ISUNKNOWN(c) && !ISNOCARD(c)) // ProcessQuery() // Handling the lookup of dll$symbols DLL_IMPLEMENTS double __stdcall ProcessQuery(const char* pquery) { if (pquery==NULL) return 0; if (strncmp(pquery,"dll$mynumber",13)==0) { return 12345.67; } return 0; } // OnLoad and OnUnload() // called once and at the beginning of a session // when the DLL gets loaded / unloaded // Do initilization / finalization here. DLL_IMPLEMENTS void __stdcall DLLOnLoad() { #ifdef OPT_DEMO_OUTPUT MessageBox(NULL, "event-load", "MESSAGE", MB_OK); #endif OPT_DEMO_OUTPUT } DLL_IMPLEMENTS void __stdcall DLLOnUnLoad() { #ifdef OPT_DEMO_OUTPUT MessageBox(NULL, "event-unload", "MESSAGE", MB_OK); #endif OPT_DEMO_OUTPUT } // DLL entry point // Technically required, but don't do anything here. // Initializations belong into the OnLoad() function, // where they get executed at run-time. // Doing things here at load-time is a bad idea, // as some functionalitz might not be properly initialized // (including error/handling). BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: #ifdef OPT_DEMO_OUTPUT AllocConsole(); #endif OPT_DEMO_OUTPUT break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: #ifdef OPT_DEMO_OUTPUT FreeConsole(); #endif OPT_DEMO_OUTPUT break; } return TRUE; }  
      Source.zip
      DllAccess.au3
    • By Satvik
      Hi 
      I am trying to open a dll using DLLOpen, however everytime i try to do so the function fails and returns -1 result. 
      I have the dll in the same folder as the auto it script. 
      Local $hDLL = DllOpen("C:\Users\310255155\Downloads\COMMGvv2\commg.dll") DllCall($hDLL, "int", "MessageBox", "hwnd", 0, "str", "Some text", "str", "Some title", "int", 0) DllClose($hDLL) MsgBox(0,'result',$hDLL)  
    • By Ontosy
      When i try to use nss3 library;
      DLLOPEN("c:\Program Files (x86)\Firefox\nss3.dll")
      It return -1.
      Why?
    • By muchado
      I have written a script that I want to use to call a DLL. However, when I call it using DLLOpen, it returns an integer rather than a handle. This would make sense if it was a "-1" error code, but instead it is a "1".
      If FileExists ( @SystemDir & "\MyDLL.dll" ) Then ConsoleWrite ( "DLL exists and is located here: " & @SystemDir & @CRLF ) Else ConsoleWrite ( "DLL not found in " & @SystemDir & @CRLF ) Exit EndIf Global $hDll = DllOpen(@SystemDir & "\MyDLL.dll") ConsoleWrite ( "DLLOpen MyDLL returns " & $hDLL & @CRLF ) If $hDll = -1 Then Exit MsgBox(0, "", "Failed to open MyDLL.dll") Global $aDLL = DllCall($hDLL, "BOOL", "Output", "str", "AdSec_Driver", "str", "ETABS" ) ConsoleWrite("!" & @error & "-" & @extended & @CRLF) ConsoleWrite ( "MyDLL returns data of type " & VarGetType( $aDLL) & @CRLF ) _ArrayDisplay($aDLL) MsgBox(0, "", $aDLL[0]) DllClose($hDll) When I run this I get the following output on the console:
      DLL exists and is located here: C:\Windows\system32 DLLOpen MyDLL returns 1 !3-0 MyDLL returns data of type Int32 "C:\Users\andrew.mole\Documents\autoit\AdSec_Driver\trunk\AdSec_Driver.au3" (197) : ==> Subscript used on non-accessible variable.: MsgBox(0, "", $aDLL[0]) MsgBox(0, "", $aDLL^ ERROR Any idea why this is?
×
×
  • Create New...