Ruby/DL
Aus Scientia
Das RGSS3 stellt neben Win32API auch diese Erweiterungsbibliothek zum Aufrufen von Funktionen in DLLs zur Verfügung.
Inhaltsverzeichnis
Allgemein
DL ist mächtiger als Win32API. Es werden von ihr u.a. die Aufrufkonventionen cdecl und stdcall und auch Rückruffunktionen unterstützt. Fehlende Dokumentation und die hohe Komplexität für viele Anwendungen sind jedoch ein großer Nachteil.
RGSS
Im RGSS3 ist nur der C-Teil dieser Erweiterungsbibliothek von Haus aus verfügbar. Der Ruby-Teil, der z.B. Import von Funktionen anhand eines Prototyps ermöglicht, muss nachträglich hinzugefügt werden.
| Klasse / Modul | Beschreibung |
|---|---|
| DL | Hauptmodul, das dynamische Speicherzuordnung beherrscht und Konstanten u.a. für die Typen beinhaltet |
| DL::DLError | allgemeine Exception |
| DL::DLTypeError | Exception, falls ein unbekannter oder inkorrekter Typ bei einem Aufruf verwendet wurde |
| DL::Handle | Klasse zum Laden einer DLL und zum Herausfinden der Adresse einer Funktion |
| DL::CFunc | Interface für eine C-Funktion |
| DL::CPtr | Interface für einen C-Zeiger |
Beispiel
command line
# Name der Win32-Funktion, die die Unicode-Version der Kommandozeilenzeichenkette zurück gibt # Doku: <http://msdn.microsoft.com/en-us/library/windows/desktop/ms683156%28v=vs.85%29.aspx> name = 'GetCommandLineW' # die DLL laden handle = DL::Handle.new 'kernel32' # Adresse unsere Funktion erhalten address = handle.sym(name) # getcommandlinew ist ein Ruby-Interface für die Funktion # Rückgabedatentyp ist zwar LPWSTR (Zeiger auf wchar_t), DL bietet jedoch nur VOIDP (void *). # Aufrufkonvention der Win32-API ist stdcall (Standard ist cdecl) getcommandlinew = DL::CFunc.new(address, DL::TYPE_VOIDP, name, :stdcall) # die Funktion GetCommandLineW aufrufen # die Funktion erwartet keine Argumente, darum bleibt das Array leer cmdline = getcommandlinew.call([]) # Wir haben nun einen Zeiger auf die Unicodekommandozeilenzeichenkette. # Die Länge brauchen wir jedoch auch (bei ANSI/char wäre das nicht nötig, aber es ist nicht mehr 1970). # wcslen gibt einen Wert mit dem Typ size_t zurück. Im RGSS3 gibt es DL::TYPE_SIZE_T jedoch nicht. wcslen = DL::CFunc.new(DL.dlopen('msvcrt').sym('wcslen'), DL::TYPE_INT) # wcslen gibt die Länge in Buchstaben zurück. Wir brauchen sie in Bytes! (sizeof(wchar_t) == 2) length = wcslen.call([cmdline]) * 2 # durch den Pointer und die Stringlänge in Byte können wir den adressierten Speicher # in einen Ruby-String konvertieren. Danach kodieren wir den String von UTF-16 (Win32-API) nach UTF-8 (RGSS3). command_line = DL::CPtr.new(cmdline, length).to_str.encode!('UTF-8', 'UTF-16LE') p command_line # => "Game.exe console test RPG ツクール"
Adresse der Bitmap-Pixel
class Bitmap def address data = DL::CPtr.new((object_id << 1) + 16).ptr info = (data + 8).ptr (info + 16).ptr.to_i # letzte Scanline! end end
Für weitere Informationen und den verbreiteteren Weg siehe den Abschnitt "Die Bitmap-Struktur" auf Bitmap.