Jump to content

Recommended Posts

Posted (edited)

It is a great thing to handle already awesome winapi dll files like some of tutorials show you already but what about using your own dll files?

To spice up your imagination, if you could handle your own dll code and incorporate it to AutoIt, there are simply no limits!

I dont see it covered anywhere so i thought to start this with a simple tutorial how to create your basic dll in c/c++ then hopefully some guys will jump in and contribute

If you are new to dll files, this post will show you how to create basic Dll.

So i say great, lets test some basic dll file, open up visual studio(anything else should be fine unless you are complete noob) and lets define few things, first thing first // note: i changed the code a bit so pictures might show different code

Chose New Project

Posted Image

- Chose Win32ConsoleApplication

- Enter desired name, click Next

Pick that you want to Create Dll File

Posted Image

- Make sure you select Dll

- Make sure you select Empty Project

First We Create header file

- Right Click on "Header Files" folder icon and chose "Add New", then lets pick "basicdll" as the name

Posted Image

Simply paste this code into the header file

#ifndef _DLL_TUTORIAL_H_
#define _DLL_TUTORIAL_H_  // This is basically to tell compiler that we want to include this code only once(incase duplication occurs), you include it in .cpp file(which we will soon do)
#include <iostream>       // Inlcude basic c++ standard library output header(this is used for output text on the screen in our code)

#define DECLDIR __declspec(dllexport)

// We #define __declspec(dllexport) as DECLDIR macro so when compiler sees DECLDIR it will just take it as __declspec(dllexport)(say that DECLDIR is for readability)
// Note that there is also __declspec(dllimport) for internal linking with others programs but since we just need to export our functions so we can use them with Autoit, thats all we need!


extern "C"  // this extern just wraps things up to make sure things work with C and not only C++
{

// Here we declare our functions(as we do with normal functions in c header files, our cpp file will define them(later). Remember that DECLDIR is just a shortcut for __declspec(dllexport)

   DECLDIR int Add( int a, int b ); 
   DECLDIR void Function( void );
}

#endif // closing #ifndef _DLL_TUTORIAL_H_

- Save it up and move on

And finally create .cpp file

- Right Click on the "Source Files" folder icon, chose add new, pick "basicdll" as the name and follow on ...

Posted Image

- Again just paste the .cpp file code...

#include <iostream>
#include <Windows.h> // this is where MessageBox function resides(Autoit also uses this function)

#include "basicdll.h" // We include our header file which contains function declarations and other instructions


extern "C" // Again this extern just solves c/c++ compatability [b]Make sure to use it because Autoit wont open dll for usage without it![/b]
{
   DECLDIR int Add( int a, int b )
   {
      return( a + b ); // Finally we define our basic function that just is a sum of 2 ints and hence returns int(c/c++ type)
   }

   DECLDIR void Function( void )
   {
      std::cout << "DLL Called! Hello AutoIt!" << std::endl; // This silly function will just output in our Autoit script "Dll Called!"
      MessageBox(0, TEXT("DLL from Autoit"), TEXT("Simple Dll..."),0);  // Use good old Message Box inside Windows Api Functions but this time with your own dll }
}

And thats it, we are done with configuration of header and source and we can compile our DLL file for later usage(note that you must set configuration properties of your project to use Unicode character set (so TEXT() macro in our .cpp works well)(Autoit)

- Right Click on the project/solution or just pick Build from menu and select build project/solution and get to here...

Posted Image

Navigate to your project dir(should be in debug folder) and there is your basic dll file with 2 simple functions to use!

So lets use them :x

Copy/paste your basicdll.dll file into the dir of your script, now lets use it with autoit

Lets use this simple function we named "Function", open up autoit script, place dll file inside same folder

$dll = DllOpen("basicdll.dll")
DllCall($dll, "none", "Function")

Results:

Posted Image

You should also get a MessageBox but this time you will let AutoIt rest and call it with your own dll to access WinApi by itself.

Not everything is always sexy and perfect, so if you just think puting "int" as return type for our Add() function, you are wrong. Our function returns int type indeed but we need to modify it a bit.

NOTE - this Add function crushes autoit script, so instead pointing "int" as our return type like this...

DllCall($dll, "int", "Add", "int", 3, "int", 5)

We need to do this:

DllCall($dll, "int:cdecl", "Add", "int", 3, "int", 5)

if you can combine the power of language like c/c++ with simplicity of Autoit by creating our own .dll's and not just using the winapi dlls and other prebuilt goodies there is no limit of what you could do with Autoit, hopefully this will be your starting point to show you that c++ is indeed worth to learn!

Thats it for now, this tutorial is based on http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9855 (source that got me into dll files), i hope you will learn from this and everyone can benefit on the end. Happy New Year and Cheers to the forums!

Edited by marko29
Posted (edited)

NOTE - the Add function crushes autoit script, i really have no idea why so if anyone knows let me know what is the problem, i use it like i should(hopefully) by doing

DllCall($dll, "int", "Add", "int", 3, "int", 5)

Maybe problem can be in this

from helpfile

Function DllCall

By default, AutoIt uses the 'stdcall' calling method. To use the 'cdecl' method place ':cdecl' after the return type.

DllCall("SQLite.dll", "int:cdecl", "sqlite3_open", "str", $sDatabase_Filename , "long*", 0).

EDIT:

I forgot to say "NICE tutorial!!" :-)

Edited by Zedna
Posted (edited)

Since i can't edit small mistake(forgot to add some code) mods you are welcome to do it or let me do it, i forgot to add #define DECLDIR __declspec(dllexport) in the header file :x, dunno why i am unable to edit things and sorry for silly mistake. Btw thanks Zedna, i ll keep playing with dll files in Autoit and perhaps add more things soon.

edit: about to try your suggestion, thanks!

Edited by marko29
Posted (edited)

$test = DllCall("basicdll.dll", "int:cdecl", "Add", "int", 2, "int", 2)
MsgBox(0,"",$test)

Just tried it, @error seems to return 0 so that is ok but MssgBox shows nothing same as console, weird but at least one step forward

I am gonna try some heavy dll file now, used to contact some listview from outside app, this listview is not possible to interact with in autoit(meaning you cant get any item text from it etc.) but trying to do it inside dll, then hooking dll to the listview thread perfectly returned everything i needed, so this is one example how you could benefit from dll if autoit has a barrier with its own functions.

Edited by marko29
Posted (edited)

$test = DllCall("basicdll.dll", "int:cdecl", "Add", "int", 2, "int", 2)
MsgBox(0,"",$test[0])

Read the helpfile carefully :x

yes, i am obviously still autoit newb, thanks for pointing on my mistake, array as result works perfectly Edited by marko29
Posted

------ Build started: Project: basicdll, Configuration: Debug Win32 ------

Compiling...

basicdll.cpp

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(15) : error C2144: syntax error : 'int' should be preceded by ';'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(15) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(16) : error C2144: syntax error : 'void' should be preceded by ';'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(16) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(16) : error C2086: 'int DECLDIR' : redefinition

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(15) : see declaration of 'DECLDIR'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(8) : error C2144: syntax error : 'int' should be preceded by ';'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(8) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(8) : error C2086: 'int DECLDIR' : redefinition

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(15) : see declaration of 'DECLDIR'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(13) : error C2144: syntax error : 'void' should be preceded by ';'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(13) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(13) : error C2086: 'int DECLDIR' : redefinition

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(15) : see declaration of 'DECLDIR'

Build log was saved at "file://c:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\basicdll\basicdll\Debug\BuildLog.htm"

basicdll - 11 error(s), 0 warning(s)

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Posted (edited)

------ Build started: Project: basicdll, Configuration: Debug Win32 ------

Compiling...

basicdll.cpp

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(15) : error C2144: syntax error : 'int' should be preceded by ';'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(15) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(16) : error C2144: syntax error : 'void' should be preceded by ';'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(16) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(16) : error C2086: 'int DECLDIR' : redefinition

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(15) : see declaration of 'DECLDIR'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(8) : error C2144: syntax error : 'int' should be preceded by ';'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(8) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(8) : error C2086: 'int DECLDIR' : redefinition

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(15) : see declaration of 'DECLDIR'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(13) : error C2144: syntax error : 'void' should be preceded by ';'

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(13) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.cpp(13) : error C2086: 'int DECLDIR' : redefinition

c:\documents and settings\administrator\my documents\visual studio 2008\projects\basicdll\basicdll\basicdll.h(15) : see declaration of 'DECLDIR'

Build log was saved at "file://c:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\basicdll\basicdll\Debug\BuildLog.htm"

basicdll - 11 error(s), 0 warning(s)

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Did you add this? #define DECLDIR __declspec(dllexport)

to your header file? As i said, i wanted to edit it but i am for some reason unable to edit posts after their creation, unless its 1minute after or so.

Also if you test Add function use int:cdecl as return type in DllCall() (as Zedna suggested.)

Edited by marko29
Posted

Also, it's worth noting that it would make more sense to create a Win32 project rather than a console application to start.

Any reason to go backwards?

Posted (edited)

Define backwards. Keep in mind the fact that a dll isn't supposed to be straight up executed like an application is.

It is win32 console project, the only console project visual studio 2010 has, i have no clue what you wanted to say but probably you misunderstood that i was creating pure win32app without console.

Btw this dll is just to get people going into DLL, not much fancy stuff. But i want to mention that i succesfully managed to add some dll functionality to my autoit script purely with custom made DLL, hooking the Dll to the app gave me all the info about the app on the plate, something i couldnt do simply with Autoit function(that didnt have hooking included) but thats another story and maybe another tutorial.

Also i am aware autoit gives us option to hook but i couldnt find appropriate examples to customize hooking to the detail i needed, if anyone has some good tutorial about this let me know, cheers

Edited by marko29
Posted (edited)

I believe you misunderstood what I said completely. I was suggesting using the Win32 Project wizard rather than the console application wizard.

I guess you are right, i did misunderstand it as you did mention pure win32project, just why would you do so and why does it matter after all?

It was empty created project anyway!

It was example of the most basic dll which is why i picked console

Edited by marko29
Posted (edited)

This is exactly my point. "Most basic dll" will never do anything console or GUI.

You are correct but as i said it was only a preface for empty project anyway, i guess you are picky person but then again i am used to do it this way on the end who cares if its console or non console when project is empty, especially people new to it wont care :x

Edited by marko29
  • 3 weeks later...
Posted (edited)

$test = DllCall("basicdll.dll", "int:cdecl", "Add", "int", 2, "int", 2)
MsgBox(0,"",$test[0])

Read the helpfile carefully :)

I'm getting the error " ==> Subscript used with non-Array variable." when I use that exact code :/

Edit: found another topic...apparently its because im on a 64bit OS. I ran the script as x86 and it worked...

is there any workaround for this so I dont have to save->run script every time, and can just hit f5 to test?

also, excellent tut, thanks very much.

Edit2: nevermind, put run as admin on scite...problem solved.

Edited by arktikk
Posted (edited)

Because the DLL is not Returning an Array for some reason, try MsgBox(0,@error,$test) instead to see what is Returned if anything?!

Edit: Typo! :)

Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...