Documentazione mIRC

Dynamic-link library

Dynamic-link library

mIRC permette di effettuare chiamate a DLL progettate per lavorare con mIRC. Il vantaggio principale è la velocità: per elaborazioni pesanti, una DLL può essere più efficiente di uno script mIRC puro.

mIRC supporta gli oggetti COM per scenari che non rientrano nelle DLL standard per mIRC.

Using a DLL

Synopsis

/dll <filename> <procname> [data]
/dll -u <filename>
$dll(<filename>, <procname>, [data])
$dllcall(<filename>, <alias>, <procname>, [data])

Switches

  • -u - Scarica la DLL.

Parameters

  • <filename> - Il file DLL da usare.
  • <procname> - Il nome della funzione o procedura da chiamare.
  • [data] - Parametri opzionali per la funzione.
  • <alias> - Con $dllcall, alias eseguito in modo asincrono alla fine della chiamata.

Creating a DLL

La pagina non spiega in dettaglio come scrivere una DLL da zero, ma specifica che chi la crea deve già conoscere lo sviluppo DLL.

Le funzioni esportate devono usare la convenzione di chiamata __stdcall e ricevere handle finestra, buffer dati, buffer parametri e due flag booleani.

#include <windows.h>
int __stdcall funcName(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause);
  • mWnd - Handle della finestra principale di mIRC.
  • aWnd - Handle della finestra da cui parte il comando.
  • data - Buffer usato per restituire un valore o per far eseguire un comando a mIRC.
  • parms - Buffer usato per passare parametri che mIRC mapperà in $1-.
  • show - È FALSE se il comando è stato chiamato in modalità quiet.
  • nopause - È TRUE se mIRC si trova in una routine critica.

I buffer data e parms seguono il line length limit di mIRC.

C++ DLL e stdcall

Per una DLL C++, viene consigliato di usare extern "C" su tutte le funzioni esportate, comprese LoadDll e UnloadDll, per evitare il normale name mangling del C++.

extern "C" int __stdcall funcName(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause);

La pagina precisa però che __stdcall introduce comunque una forma di mangling, e suggerisce quindi l’uso di un file .def oppure di direttive #pragma in Visual Studio.

Viene anche menzionato l’equivalente GCC: __attribute__((stdcall)).

Return value

  • 0 - mIRC deve eseguire /halt.
  • 1 - mIRC deve continuare l’elaborazione.
  • 2 - La DLL ha scritto in data un comando da eseguire.
  • 3 - La DLL ha scritto in data il valore da restituire tramite $dll().

Questa logica si applica alle chiamate con $dll o /dll.

Keeping a DLL loaded

Per impostazione predefinita, una DLL viene scaricata subito dopo la chiamata. Per mantenerla caricata, è possibile implementare una routine LoadDll().

void __stdcall LoadDll(LOADINFO*);
typedef struct {
  DWORD mVersion;
  HWND mHwnd;
  BOOL mKeep;
  BOOL mUnicode;
} LOADINFO;
  • mVersion - Versione di mIRC.
  • mHwnd - Handle della finestra principale.
  • mKeep - Se TRUE, la DLL resta caricata.
  • mUnicode - Se TRUE, i dati testuali vengono trattati come Unicode.

In modalità Unicode, la firma della funzione usa buffer wide char.

int __stdcall funcName(HWND mWnd, HWND aWnd, wchar *data, wchar *parms, BOOL show, BOOL nopause);

Unloading the DLL

mIRC scarica automaticamente una DLL se non viene usata per dieci minuti oppure quando il programma termina.

È possibile definire una routine UnloadDll() per fare cleanup.

int __stdcall UnloadDll(int mTimeout);
  • 0 - Scaricamento dovuto a /dll -u.
  • 1 - Scaricamento per inattività; la DLL può anche chiedere di restare caricata.
  • 2 - Scaricamento durante la chiusura di mIRC.

Examples

La pagina originale include un primo esempio completo in Visual Studio/C++, con esportazione delle funzioni tramite #pragma, uso di SendMessage(), e routine di inizializzazione e cleanup.

Include anche un secondo esempio in C compilato con GCC su Windows, che mostra una DLL minima con convenzione stdcall.