Jump to content
Sign in to follow this  
jtredez

DLL development questions (return value and callback)

Recommended Posts

jtredez

Hello,

I would like to develop a DLL for autoit but I have some questions.

I use Autoit 3.3.9.0beta and codeblock with mingw for the DLL part.

I have the DLL, a external program developped in C to test this DLL and an autoit program to test this DLL.

The DLL have only one function: addition to add two integer and return the result.

This is part of my source code (I put the full project in attachment):

int DLL_EXPORT addition(int integer1, int integer2) {
    return integer1 + integer2;
}
#define DLL_EXPORT __declspec(dllexport)
#ifdef __cplusplus
extern "C"
{
#endif
int DLL_EXPORT addition(int integer1, int integer2);
#ifdef __cplusplus
}
#endif
local $hDll = DllOpen("LibTest.dll")
$result = DllCall($hDll, "int:cdecl","addition", "int",3, "int",7)
MsgBox(4096, "In AutoIt", "3 + 7 = " & $result & @CRLF & "error = " & @error)
DllClose($hDll)
Exit
  • The returned value on my DLL function is correct (=10) with my C test program but not in autoit (=0). The parameters is correctly passed to the DLL in both case (I display it in the DLL with a msgbox). I have tested with __stdcall and without. What is wrong with my code?
  • When I use the __stdcall version, my DLL function name change to addition@8, why this? and how to avoid this? (sorry I not realy familiar with DLL development).
  • I would like to call an autoit function in my DLL. I suppose I need to use the DllCallbackRegister to get a pointer on my autoit function and to pass it to a function in my DLL, like what it’s done in the Example of DllCallbackRegister with EnumWindows. But in my DLL how I call this pointer? Does I need a specific mechanism or I can call it like another C function pointer? And how to pass parameters to the autoit callback function and eventualy get a return value?
Thank you for your help.

dll.zip

Share this post


Link to post
Share on other sites
SkinnyWhiteGuy

Reread the DllCall help entry, the result variable you have doesn't work the way you are using it.

Share this post


Link to post
Share on other sites
Beege

The returned value on my DLL function is correct (=10) with my C test program but not in autoit (=0). The parameters is correctly passed to the DLL in both case (I display it in the DLL with a msgbox). I have tested with __stdcall and without. What is wrong with my code?

jtredez, Unless the call to DllCall() fails, the function will return an array. Your dll is fine. Just change the return value in the msgbox to :

MsgBox(4096, "In AutoIt", "3 + 7 = " & $result[0] & @CRLF & "error = " & @error)

When I use the __stdcall version, my DLL function name change to addition@8, why this? and how to avoid this? (sorry I not realy familiar with DLL development).

You can read about why this happens here.

Share this post


Link to post
Share on other sites
Shaggi

for #3:

Func Myau3Func($a, $b, $c)
    ConsoleWrite("Myfunc called with a = " & $a & " b = " & $b & " c = " & $c & @LF)
    Return $a + $b + $c
EndFunc
$cb = DllCallBackRegister("Myau3Func","int","int;int;int")
$pcb = DllCallBackGetPtr($cb)
DllCall($yourdll, "void:cdecl", "OnAutoItFunc","ptr",$pcb)
While sleep(10)
Wend
;C dll :
typedef int (_stdcall * au3_func)(int,int,int);

void _cdecl OnAutoItFunc(void * func) {
    int ret = 0;
    if(func) {
        au3_func MyAu3Func = (au3_func) func;
        ret  = MyAu3Func(10,20,30);
    }
}

e: symbol issues

Edited by Shaggi

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites
jtredez

Thank you, your answers helped me a lot.

Just one more clarification for the question #2:

Now I understand why I have this "name-decoration".

If I compile my DLL by declaring the function with __stdcall, when I call the function in autoit I need to do it like this:

$result = DllCall($hDll, "int","addition@8", "int",3, "int",7)

The default call convention on autoit is __stdcall, so I assumes I doesn't need to put the "name-decoration" to find this function, but it's not the case.

I would like to write it like this (without the :cdecl and without the @8):

$result = DllCall($hDll, "int","addition", "int",3, "int",7)

Share this post


Link to post
Share on other sites
wraithdu

If your function is cdecl, then you must use :cdecl in AutoIt. The extra 6 characters are really that much work?

If that's the case then I'm sure setting up a modules.def file in your C IDE will be too much as well... (hint)

Edited by wraithdu

Share this post


Link to post
Share on other sites
ProgAndy

Since you are using MinGW, you could use the switch --add-stdcall-alias or --kill-at.

http://forums.codeblocks.org/index.php?topic=2616.msg20754#msg20754

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites
jtredez

I have found a usefull documentation on how to write DLL with MinGW (in case someone interested):

http://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/

http://www.transmissionzero.co.uk/computing/advanced-mingw-dll-topics/

MinGW doesn't have the same "name-decoration" as VisualC++ and need Definition file (thank wraithdu to point me on this) to solve this issue (see link #2 for explanation).

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  

  • Similar Content

    • Terenz
      By Terenz
      Hello,
      Someone is so kind to compile for me this DLL?
      https://github.com/stephane/libmodbus/tree/master/src/win32
      Many thanks!
    • cdeb
      By cdeb
      I'm trying to verify which is the default scanner and if it is different from what I need to propose a choice among those available.
      All this is possible with eztw32.dll however I can not make certain functions work
      Are these:
      int TWAIN_GetDefaultSourceName(LPSTR pzName)
      string TWAIN_DefaultSourceName()
      int TWAIN_GetSourceList(void)
      source: http://www.eztwain.com/pub/eztp/EZTwain_User_Guide.pdf
      I tried this way but they do not work:
      Local $pzName
      $pzName = DllCall($pathDLL,"int","TWAIN_DefaultSourceName") ;
      $rc = DllCall($pathDLL,"int","TWAIN_GetDefaultSourceName", "str*", $pzName) ;
      $rc = DllCall($pathDLL,"int","TWAIN_GetDefaultSourceName","str", $pzName) ;
      $rc = DllCall($pathDLL,"int","TWAIN_GetSourceList")
      $rc = DllCall($pathDLL,"int","TWAIN_GetSourceList", "NONE", "") ;
       
      Can anyone help me?
      Everything else works, here is the code:
       
      Local $pathDLL = @ScriptDir&"\_res\eztw32.dll" Local $rc = DllCall($pathDLL,'int','TWAIN_EasyVersion') if @error <> 0 then MsgBox(16+262144, "DllCall Error", "Error load eztw32.dll") else ConsoleWrite('--> eztw32.dll version: ' & $rc[0]/100 & @CRLF) $rc = DllCall($pathDLL,"int","TWAIN_IsAvailable") If @error > 0 Then MsgBox(16+262144, "DllCall Error", "Error call DLL - TWAIN_IsAvailable") if $rc[0] <> 0 then ConsoleWrite('--> TWAIN available: RC = ' & $rc[0]&@CRLF) ;;;;;;;;;;;;;;;;;;;;;; I NEED HERE ;manual select scanner Local $hwnd $rc = DllCall($pathDLL,"long","TWAIN_SelectImageSource",'hwnd',$hwnd) ConsoleWrite('--> TWAIN_SelectImageSource = ' & $rc[0]&@CRLF) if $rc[0] <> 0 then ConsoleWrite("--> TWAIN device selected"&@CRLF) else ConsoleWrite("--> no TWAIN device selected"&@CRLF) endif Else ConsoleWrite('--> TWAIN NOT available: RC = ' & $rc[0]&@CRLF) ; es: 0 endif endif thank you
    • Mannyfresh31
      By Mannyfresh31
      Hi Everybody I want know if there is someone kind enough to help me translate this code in to Autoit please don't blame me cause I'm a newbe 
      here is the code I need to translate also I want know if it's possible to look through a DLL  functions
       
      Declaration in Visual Basic 6: 
      Simply add the DLL import unit 'cashdll.bas' to your project, 
      or add following line to the declarations part: 
      Declare Function CASH_OPENCOM Lib "CASH.DLL" (ByVal CASH_COMPORT As Long) As Long 
       
      Declaration in Visual Basic 6: 
      Simply add the DLL import unit 'cashdll.bas' to your project, 
      or add following line to the declarations part: 
      Declare Sub CASH_CLOSECOM Lib "CASH.DLL" ()
       
       
      and here is the code I have written so far
      down below is the DLL attached also a screen shot of the  exit code of SciTE
      #include<Array.au3> $CashDLL = DllOpen("C:\Users\manue\Downloads\Casll DLL\cash.dll") if $CashDLL Then MsgBox (0,"","CashDLL Open",0) $HOPPER_OPENCOM = DllCall($CashDLL,"LONG","HOPPER_OPENCOM") if isarray ($HOPPER_OPENCOM) Then _Arraydisplay ($HOPPER_OPENCOM) Else MsgBox (0,"",@error,0) EndIf $HOPPER_CLOSECOM = DllCall($CashDLL,"NONE","HOPPER_CLOSECOM") if isarray ($HOPPER_CLOSECOM) Then _Arraydisplay ($HOPPER_CLOSECOM) Else MsgBox (0,"",@error,0) EndIf DllClose ($CashDLL)  
       

      cash.dll
    • marcoauto
      By marcoauto
      Ciao
      I would like to control an ATEM Video Mixer from autoit. I downloaded his SDK which is written in c ++ and I found the sequences to interface, but I was not able to convert the script to self.
      The instructions say to follow this sequence:
      and to connectTo with C++ is:
      string address = "192.168.1.240"; _BMDSwitcherConnectToFailure failureReason = 0; IBMDSwitcher switcher = null; var discovery = new CBMDSwitcherDiscovery(); discovery.ConnectTo(address, out switcher, out failureReason); From Blackmagic SDK:
      IBMDSwitcherDiscovery::ConnectTo method
      The ConnectTo method connects to the specified switcher and returns an IBMDSwitcher object interface for the switcher.
      Syntax HRESULT ConnectTo (string deviceAddress, IBMDSwitcher** switcherDevice, BMDSwitcherConnectToFailure* failReason); Parameters: deviceAddress in Network hostname or IP address of switcher to connect to. switcherDevice out IBMDSwitcher object interface for the connected switcher. failReason out Reason for connection failure as a BMDSwitcherConnectToFailure value. So, I have I tried these solutions but with non success:
      $DllName =@ScriptDir&"\BMDSwitcherAPI.dll" $result = DllCall($DllName, "none", "IBMDSwitcherDiscovery::ConnectTo" & @CRLF) ConsoleWrite("DLLCall Result: " & $result & @CRLF) and I have tried also create an Object (That I think is the best way solution):
      #include <MsgBoxConstants.au3> $oSwitcher=ObjCreate("IBMDSwitcher") If IsObj($oSwitcher) Then MsgBox(64, "", "Object $oSwitcher created successfully") EndIf $oAtem=ObjCreate("IBMDSwitcherDiscovery") If IsObj($oAtem) Then MsgBox(64, "", "Object $oAtem created successfully") EndIf $failureReason =ObjCreate("_BMDSwitcherConnectToFailure") If IsObj($failureReason) Then MsgBox(64, "", "Object $failureReason created successfully") EndIf $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") ; Install a custom error handler Global $errore,$oSwitcher1 $oAtem.ConnectTo("192.168.1.36",$oSwitcher,$failureReason); ; This is the custom error handler Func MyErrFunc() $HexNumber = Hex($oMyError.number, 8) MsgBox(0, "", "We intercepted a COM Error !" & @CRLF & _ "Number is: " & $HexNumber & @CRLF & _ "Windescription is: " & $oMyError.windescription & @CRLF & _ "Source is: " & $oMyError.source & @CRLF & _ "Description is: " & $oMyError.description & @CRLF & _ "Helpfile is: " & $oMyError.helpfile & @CRLF & _ "Helpcontext is: " & $oMyError.helpcontext & @CRLF & _ "Lastdllerror is: " & $oMyError.lastdllerror & @CRLF & _ "Scriptline is: " & $oMyError.scriptline) EndFunc ;==>MyErrFunc But the result is:
      We intercepted a COM Error !
      Number is: 000000A9
      Windescription is: Variable must be of type 'Object'.
      Source is: 
      Description is: 
      Helpfile is: 
      Helpcontext is: 
      Lastdllerror is: 0
      Scriptline is: 17
      The BMDSwitcherAPI.dll is registered in system. Can someone help me?
      Grazie
      Marco
    • Earthshine
      By Earthshine
      This baby can do almost any language! I found Gleany on this site and set it up on a fresh win10 install. all i would need to do to make it build an exe of the search files app we discovered is the .NET Target Framework download to build 100 % but the exe works and generates! You also need to add the path the the version of csc.exe that you want to run. MSBuild is part of .NET and can read your .csproj file.
      YOU can develop .NET OR C/C++ on this baby!
      Super lightweight (fit for crappy laptops), and you can use any dev compilers you wish, Ming, MS, etc, whatever.
      To use the build, you need to open the csproj file, else, to check your syntax it can compile individual files as well. The warning are because I do not have the .NET 4.6 Targeting Pack installed... LOL, and I could get rid of the Core warning, yes, I did not want to build a .NET Core.dll I wanted a live x64 exe! Told you MSBUILD could handle .CSPROJ, .VBPROJ, and all others Microsoft. Don't let Visual Code or Visual Studio slow you down, although, this works with Visual Code as well but there is only debugging in CORE.DLL projects

      ListFiles Example.zip
       

×