About This File
π AutoIt DLL Integration - Complete Guide
Β
π― Overview
This repository contains comprehensive examples and templates for creatingΒ two types of DLL calling conventionsΒ for use with AutoIt:
-
__stdcallΒ ConventionΒ (Windows API Standard) -
__cdeclΒ ConventionΒ (C Default)
Both conventions work perfectly with AutoIt, but each has its own advantages and use cases. This guide will help you understand the differences and choose the right one for your project.
π Repository Structure
AutoIT_DLL/
βββ π AutoIT_DLL_StdCall/ ← Windows API standard (__stdcall)
β βββ Template_DLL.cpp
β βββ TestDLL.cpp
β βββ TestDLL_Master.cpp
β βββ template_test.au3
β βββ *.def files
β βββ Documentation files
β
βββ π AutoIT_DLL_cdecl/ ← C default convention (__cdecl)
β βββ Template_DLL.cpp
β βββ TestDLL.cpp
β βββ TestDLL_Master.cpp
β βββ template_test.au3
β βββ Documentation files
β
βββ π README.md (this file)
π Key Differences Summary
| Feature |
StdCallΒ (__stdcall)
|
CdeclΒ (__cdecl)
|
|---|---|---|
| Calling Convention | Callee cleans stack | Caller cleans stack |
| Windows API Standard | β Yes (same as kernel32.dll) | β No |
| Variable Arguments | β Not supported | β Supported (printf-style) |
| Binary Size | Smaller (cleanup in one place) | Larger (cleanup in multiple places) |
| AutoIt Syntax |
Clean:Β "int"
|
Explicit:Β "int:cdecl"
|
| DEF File Required | β Yes (for exports) | β No (exports work without) |
| Performance | Slightly faster | Slightly slower |
| Name Decoration |
_Function@bytes
|
_Function
|
| C++ Declaration |
EXPORT int __stdcall Func()
|
EXPORT int Func()
|
| AutoIt DllCall |
DllCall($h, "int", "Func")
|
DllCall($h, "int:cdecl", "Func")
|
π Detailed Comparison
1οΈβ£ StdCall Convention (__stdcall)
π― What is StdCall?
StdCallΒ is the standard calling convention for Windows API functions. TheΒ calleeΒ (the function being called) is responsible for cleaning up the stack after the function returns.
β Advantages
-
Windows API Compatibility
- Same convention used byΒ user32.dll,Β kernel32.dll, and all Windows system DLLs
- Familiar to Windows developers
- Matches Microsoft documentation examples
-
Cleaner AutoIt Syntax
- No need forΒ :stdcallΒ suffix in DllCall
- More intuitive for beginners
; Clean and simple $result = DllCall($hDll, "int", "Add", "int", 5, "int", 3) -
Smaller Binary Size
- Stack cleanup code exists in only one place (inside the function)
- Results in smaller DLL files
-
Slightly Better Performance
- Function knows exactly how many bytes to clean
- More efficient stack cleanup
-
Name Mangling Predictability
- Decorated names follow pattern:Β _FunctionName@bytes
- Easier to debug with dependency walker tools
β Disadvantages
-
Requires DEF File
- Must createΒ .defΒ file to export functions without name decoration
- Additional maintenance overhead
LIBRARY MyDLL EXPORTS Add Subtract -
No Variable Arguments
- Cannot create functions likeΒ printf(const char* fmt, ...)
- All parameters must be known at compile time
-
Less Portable
- Primarily a Windows convention
- Not commonly used on other platforms
π§ Implementation in C++
// Define export macro with __stdcall
#define EXPORT extern "C" __declspec(dllexport) __stdcall
// Simple integer function
EXPORT int Add(int a, int b) {
return a + b;
}
// String function
EXPORT const char* ToUpperCase(const char* input) {
static char buffer[1024];
// ... convert to uppercase ...
return buffer;
}
// Array function
EXPORT int SumArray(int* array, int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += array[i];
}
return sum;
}
Required DEF FileΒ (MyDLL.defπ
LIBRARY MyDLL
EXPORTS
Add
ToUpperCase
SumArray
π§ Calling from AutoIt
; Open the DLL
Global $hDll = DllOpen("MyDLL.dll")
If $hDll = -1 Then
MsgBox(0, "Error", "Failed to open DLL!")
Exit
EndIf
; Call integer function - Clean syntax!
$result = DllCall($hDll, "int", "Add", "int", 10, "int", 20)
ConsoleWrite("10 + 20 = " & $result[0] & @CRLF) ; Output: 30
; Call string function
$result = DllCall($hDll, "str", "ToUpperCase", "str", "hello world")
ConsoleWrite("Result: " & $result[0] & @CRLF) ; Output: HELLO WORLD
; Call array function
Local $array = DllStructCreate("int[5]")
DllStructSetData($array, 1, 10, 1) ; array[0] = 10
DllStructSetData($array, 1, 20, 2) ; array[1] = 20
DllStructSetData($array, 1, 30, 3) ; array[2] = 30
DllStructSetData($array, 1, 40, 4) ; array[3] = 40
DllStructSetData($array, 1, 50, 5) ; array[4] = 50
$result = DllCall($hDll, "int", "SumArray", "ptr", DllStructGetPtr($array), "int", 5)
ConsoleWrite("Sum: " & $result[0] & @CRLF) ; Output: 150
; Close the DLL
DllClose($hDll)
2οΈβ£ Cdecl Convention (__cdecl)
π― What is Cdecl?
CdeclΒ is the default calling convention in C and C++. TheΒ callerΒ is responsible for cleaning up the stack after the function call, which allows variable-length argument lists.
β Advantages
-
Variable Arguments Support
- Can create functions with variable argument lists
- Supports printf-style functions
EXPORT void LogMessage(const char* format, ...) { va_list args; va_start(args, format); vprintf(format, args); va_end(args); } -
No DEF File Required
- Functions export cleanly withoutΒ .defΒ file
- Simpler project structure
-
C/C++ Default Convention
- Standard in C/C++ world
- Most portable across compilers and platforms
-
Easier Debugging
- Function names not decorated in DLL
- Simpler with tools like Dependency Walker
β Disadvantages
-
Requires :cdecl Suffix in AutoIt
- Must specify calling convention explicitly
- More verbose syntax
; Must use :cdecl suffix $result = DllCall($hDll, "int:cdecl", "Add", "int", 5, "int", 3) -
Slightly Larger Binaries
- Stack cleanup code duplicated at each call site
- Every caller must include cleanup code
-
Not Windows API Standard
- Different from Windows system DLLs
- May confuse Windows API developers
-
Slightly Slower
- Caller must clean up stack
- More instructions per call
π§ Implementation in C++
// Define export macro WITHOUT calling convention (defaults to __cdecl)
#define EXPORT extern "C" __declspec(dllexport)
// Simple integer function
EXPORT int Add(int a, int b) {
return a + b;
}
// String function
EXPORT const char* ToUpperCase(const char* input) {
static char buffer[1024];
// ... convert to uppercase ...
return buffer;
}
// Array function
EXPORT int SumArray(int* array, int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += array[i];
}
return sum;
}
// Variable arguments function (ONLY POSSIBLE WITH CDECL!)
EXPORT int SumVariadic(int count, ...) {
va_list args;
va_start(args, count);
int sum = 0;
for (int i = 0; i < count; i++) {
sum += va_arg(args, int);
}
va_end(args);
return sum;
}
No DEF File Needed!Β - Functions export automatically.
π§ Calling from AutoIt
; Open the DLL
Global $hDll = DllOpen("MyDLL.dll")
If $hDll = -1 Then
MsgBox(0, "Error", "Failed to open DLL!")
Exit
EndIf
; Call integer function - Must use :cdecl suffix
$result = DllCall($hDll, "int:cdecl", "Add", "int", 10, "int", 20)
ConsoleWrite("10 + 20 = " & $result[0] & @CRLF) ; Output: 30
; Call string function
$result = DllCall($hDll, "str:cdecl", "ToUpperCase", "str", "hello world")
ConsoleWrite("Result: " & $result[0] & @CRLF) ; Output: HELLO WORLD
; Call array function
Local $array = DllStructCreate("int[5]")
DllStructSetData($array, 1, 10, 1)
DllStructSetData($array, 1, 20, 2)
DllStructSetData($array, 1, 30, 3)
DllStructSetData($array, 1, 40, 4)
DllStructSetData($array, 1, 50, 5)
$result = DllCall($hDll, "int:cdecl", "SumArray", "ptr", DllStructGetPtr($array), "int", 5)
ConsoleWrite("Sum: " & $result[0] & @CRLF) ; Output: 150
; Note: Variable argument functions are difficult to call from AutoIt
; Even though cdecl supports them in C++, AutoIt's DllCall doesn't handle varargs
; Close the DLL
DllClose($hDll)
π Which One Should You Choose?
ChooseΒ StdCallΒ (__stdcall) if:
β
You wantΒ cleaner AutoIt syntaxΒ withoutΒ :cdeclΒ suffix
β
You're makingΒ Windows-specific DLLs
β
You wantΒ maximum compatibilityΒ with Windows API conventions
β
You wantΒ slightly better performance
β
You don't need variable argument functions
β
You're comfortable creatingΒ .defΒ files
π Recommended for most AutoIt users!
ChooseΒ CdeclΒ (__cdecl) if:
β
You needΒ variable argument functionsΒ (printf-style)
β
You wantΒ simpler project structureΒ (no .def files)
β
You preferΒ C/C++ standard conventions
β
You're porting existing C/C++ libraries
β
You don't mind theΒ :cdeclΒ suffix in AutoIt
π Recommended for advanced C++ developers or when porting existing code
π Quick Start Guide
For StdCall Version:
-
Navigate to folder:
cd AutoIT_DLL_StdCall -
Build DLL:
msbuild Template_DLL.vcxproj /p:Configuration=Release /p:Platform=x64 /t:Rebuild -
Test with AutoIt:
"C:\Program Files (x86)\AutoIt3\AutoIt3_x64.exe" template_test.au3 -
Read documentation:
-
README.mdΒ - Project overview -
TEMPLATE_QUICKSTART.mdΒ - 5-minute getting started -
CODING_GUIDE.mdΒ - Complete coding reference
-
For Cdecl Version:
-
Navigate to folder:
cd AutoIT_DLL_cdecl -
Build DLL:
msbuild Template_DLL.vcxproj /p:Configuration=Release /p:Platform=x64 /t:Rebuild -
Test with AutoIt:
"C:\Program Files (x86)\AutoIt3\AutoIt3_x64.exe" template_test.au3 -
Read documentation:
-
README_TEMPLATE.mdΒ - Template guide -
TEMPLATE_QUICKSTART.mdΒ - Quick start -
CODING_GUIDE.mdΒ - Complete reference
-
π Data Type Reference (Both Conventions)
| C++ Type | AutoIt Type | Description | Example |
|---|---|---|---|
int
|
"int"
|
32-bit integer |
DllCall($h, "int", "Add", "int", 5)
|
long
|
"long"
|
32-bit integer |
DllCall($h, "long", "GetSize")
|
float
|
"float"
|
32-bit float |
DllCall($h, "float", "Sqrt", "float", 16.0)
|
double
|
"double"
|
64-bit float |
DllCall($h, "double", "Pi")
|
bool
|
"boolean"
|
Boolean value |
DllCall($h, "boolean", "IsValid")
|
const char*
|
"str"
|
String (ANSI) |
DllCall($h, "str", "Echo", "str", "hi")
|
const wchar_t*
|
"wstr"
|
String (Unicode) |
DllCall($h, "wstr", "Echo", "wstr", "hi")
|
void*
|
"ptr"
|
Pointer |
DllCall($h, "int", "Sum", "ptr", $array)
|
BYTE*
|
"byte*"
|
Byte array |
DllCall($h, "int", "Read", "byte*", $buf)
|
void
|
"none"
|
No return |
DllCall($h, "none", "Print", "str", "hi")
|
int64_t
|
"int64"
|
64-bit integer |
DllCall($h, "int64", "BigSum")
|
HWND
|
"hwnd"
|
Window handle |
DllCall($h, "int", "Proc", "hwnd", $hwnd)
|
Important:Β For cdecl, addΒ :cdeclΒ suffix to return type:
; StdCall
$r = DllCall($h, "int", "Add", "int", 5, "int", 3)
; Cdecl
$r = DllCall($h, "int:cdecl", "Add", "int", 5, "int", 3)
π‘οΈ Common Best Practices (Both Conventions)
1. Always Validate Inputs
EXPORT int SafeDivide(int a, int b) {
if (b == 0) {
SetLastError("Division by zero!");
return 0;
}
return a / b;
}
2. Use Thread-Safe Code
// Use mutex for shared data
static std::mutex g_stringMutex;
static char g_stringBuffer[4096];
EXPORT const char* ProcessString(const char* input) {
std::lock_guard<std::mutex> lock(g_stringMutex);
// ... process string into g_stringBuffer ...
return g_stringBuffer;
}
3. Provide Error Retrieval
static char g_lastError[512] = {0};
void SetLastError(const char* error) {
strncpy_s(g_lastError, sizeof(g_lastError), error, _TRUNCATE);
}
EXPORT const char* GetLastError() {
return g_lastError;
}
4. Track Statistics
static std::atomic<uint64_t> g_totalCalls{0};
static std::atomic<uint64_t> g_errorCount{0};
EXPORT int MyFunction(int x) {
g_totalCalls++;
if (x < 0) {
g_errorCount++;
return -1;
}
return x * 2;
}
EXPORT uint64_t GetTotalCalls() {
return g_totalCalls;
}
5. Always Check in AutoIt
$result = DllCall($hDll, "int", "Divide", "int", 10, "int", 0)
If @error Then
MsgBox(0, "Error", "DllCall failed!")
Else
; Check the result
If $result[0] = 0 Then
; Get DLL error message
$err = DllCall($hDll, "str", "GetLastError")
MsgBox(0, "Error", $err[0])
EndIf
EndIf
π Available Examples
Both folders contain identical functionality, just different calling conventions:
1.Β Template_DLLΒ - Production Template
- Safe coding skeleton
- Error handling system
- Statistics tracking
- Ready to customize
2.Β TestDLLΒ - Basic Operations
- Integer, float, double math
- String processing
- Array handling
- Structure operations
3.Β TestDLL_AsyncΒ - Concurrency
- Thread pools
- Async operations
- Blocking/non-blocking calls
- Race condition demos
4.Β TestDLL_ExtendedΒ - Advanced Types
- All AutoIt data types
- Complex structures
- Callback functions
- Windows types (HWND, LPARAM)
5.Β TestDLL_MasterΒ - Complete Library
- 100+ functions
- 12 feature sections
- Production-ready
- Comprehensive examples
6.Β TestDLL_StressTestΒ - Performance
- Million+ call tests
- Memory leak detection
- Throughput measurement
- Stability testing
β οΈ Important Warnings
1. Don't Mix Calling Conventions!
// β WRONG - Will cause stack corruption!
// DLL uses __stdcall but AutoIt calls with :cdecl
EXPORT int __stdcall Add(int a, int b) { return a + b; }
// AutoIt: DllCall($h, "int:cdecl", "Add", "int", 5, "int", 3) β
// β
CORRECT - Calling convention matches
EXPORT int __stdcall Add(int a, int b) { return a + b; }
// AutoIt: DllCall($h, "int", "Add", "int", 5, "int", 3) β
2. Rebuild Everything When Switching
If you switch from cdecl to stdcall (or vice versa):
-
Delete all oldΒ
.dllΒ andΒ.objΒ files - Rebuild everything from scratch
- Update all AutoIt scripts
3. String Buffer Safety
// β WRONG - Local buffer destroyed after return!
EXPORT const char* GetName() {
char buffer[100] = "John";
return buffer; // Danger! Buffer goes out of scope
}
// β
CORRECT - Static buffer persists
EXPORT const char* GetName() {
static char buffer[100] = "John";
return buffer; // Safe!
}
4. Check DLL Architecture
; Make sure DLL architecture matches AutoIt
If @AutoItX64 Then
$dll = "MyDLL_x64.dll" ; 64-bit DLL for 64-bit AutoIt
Else
$dll = "MyDLL_x86.dll" ; 32-bit DLL for 32-bit AutoIt
EndIf
π§ Build Requirements
- Visual Studio 2019Β or later (Community Edition works)
- Windows SDKΒ (usually installed with Visual Studio)
- AutoIt v3Β (for testing scripts)
Build Commands:
# For x64 (64-bit)
msbuild YourProject.vcxproj /p:Configuration=Release /p:Platform=x64 /t:Rebuild
# For x86 (32-bit)
msbuild YourProject.vcxproj /p:Configuration=Release /p:Platform=Win32 /t:Rebuild
π Learning Path
For Beginners:
- β Read this README completely
- β Choose StdCall (simpler AutoIt syntax)
-
β
ReadΒ
AutoIT_DLL_StdCall/TEMPLATE_QUICKSTART.md -
β
Build and testΒ
Template_DLL - β Modify template for your needs
-
β
ReadΒ
CODING_GUIDE.mdΒ for details
For Advanced Users:
- β Understand both calling conventions
-
β
StudyΒ
TestDLL_Master.cppΒ source code -
β
Learn async patterns inΒ
TestDLL_Async -
β
Test all data types inΒ
TestDLL_Extended -
β
Run performance tests withΒ
TestDLL_StressTest - β Contribute improvements!
π€ Contributing
If you find issues or want to improve the examples:
- Test your changes thoroughly
- Document any new patterns
- Update relevant README files
- Ensure both x86 and x64 builds work
π License
These examples are provided as educational resources. Feel free to use, modify, and distribute for any purpose.
π Additional Resources
- AutoIt DllCall Documentation:Β https://www.autoitscript.com/autoit3/docs/functions/DllCall.htm
- AutoIt DllStruct Documentation:Β https://www.autoitscript.com/autoit3/docs/functions/DllStructCreate.htm
- Microsoft Calling Conventions:Β https://docs.microsoft.com/en-us/cpp/cpp/calling-conventions
- Windows API Reference:Β https://docs.microsoft.com/en-us/windows/win32/api/
π Support
For questions and issues:
- Check the documentation in each folder
- Review the example code and tests
- Search AutoIt forums
- Review Microsoft's calling convention documentation
Happy Coding! π
Remember:Β Both conventions work perfectly - choose based on your specific needs!
π Quick Reference Card
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β QUICK REFERENCE β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β β
β π STDCALL (Windows API Standard) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β C++: EXPORT int __stdcall Add(int a, int b) β
β DEF: Required (exports in .def file) β
β AutoIt: DllCall($h, "int", "Add", "int", 5, "int", 3) β
β Use: β
Most Windows projects, cleaner syntax β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β π CDECL (C Default Convention) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β C++: EXPORT int Add(int a, int b) β
β DEF: Not required β
β AutoIt: DllCall($h, "int:cdecl", "Add", "int", 5, "int", 3) β
β Use: β
Variable args, porting C libraries β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Author
Dao Van Trong - TRONG.PRO
Β
Edited by Trong