DLL & Python

Kürzlich interessierte ich mich für das Thema der Verwendung von DLLs aus Python. Außerdem war es interessant, ihre Struktur zu verstehen, falls Sie die Quelle der Bibliotheken ändern müssen. Nach dem Studium verschiedener Ressourcen und Beispiele zu diesem Thema wurde klar, dass die Verwendung dynamischer Bibliotheken die Funktionen von Python erheblich erweitern kann. Meine eigenen Ziele wurden erreicht, und damit die Erfahrung nicht vergessen wurde, beschloss ich, sie in Form eines Artikels zusammenzufassen - um mein Wissen und meine nützlichen Quellen zu strukturieren und gleichzeitig dieses Thema besser zu verstehen.
Unter dem Schnitt finden Sie einen Artikel mit verschiedenen Beispielen, Quellen und Erklärungen dafür.
Inhalt
- DLL-Struktur
- DLL & Python
- DLL-Verbindung
- Datentypen in C und Python
- Argumente funktionieren und geben Werte zurĂĽck
- Eigene DLL und deren Verwendung
- NĂĽtzliche Links:
, .
DLL
DLL — Dynamic Link Library — () Windows. , . .EXE — , DLL .
, , Microsoft: DLL?.
, , , .
DLL , -. . DllMain
, DLL . .

1 — template, Code Blocks DLL.
1 , Code Blocks, DLL. :
#define DLL_EXPORT __declspec(dllexport)
void DLL_EXPORT SomeFunction(const LPCSTR sometext);
extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
DllMain
. (fdwReason):
DLL_PROCESS_ATTACH – DLL. DLL . DllMain , - .
DLL_PROCESS_DETACH – DLL . DllMain .
DLL_THREAD_ATTACH – , DLL, . DLL - ? , .
DLL_THREAD_DETACH – , , DLL. "" ( ), .
, DLL , , .
DllMain
, fdwReason
, :
- lpvReserved DLL:
- hinstDLL DLL. EXE- DLL-, , .
: DLL.
1 SomeFunction
, . , , __declspec(dllexport)
. , :
#define DLL_EXPORT __declspec(dllexport)
void DLL_EXPORT SomeFunction(const LPCSTR sometext);
, , .
DLL & Python
, , DLL, , , , Code Blocks DLL.
DLL
Python , ctypes
. ctypes , .
DLL, Python. :
- cdll — , DLL . cdecl.
- windll — stdcall. cdll.
- oledll — stdcall , Windows HRESULT. WindowsError.
.
Windows DLL , — printf()
. msvcrt.dll
C:\WINDOWS\System32
.
Python:
from ctypes import *
lib = cdll.msvcrt
lib.printf(b"From dll with love!\n")
var_a = 31
lib.printf(b"Print int_a = %d\n", var_a)
:
From dll with love!
Print int_a = 31
windll
oledll
, , .
, dll. ctypes
LoadLibrary
. CDLL
, cdll.LoadLibrary
. , msvcrt.dll.
Python:
from ctypes import *
lib = cdll.LoadLibrary(r"C:\Windows\System32\msvcrt.dll")
lib.printf(b"From dll with love!\n")
lib_2 = CDLL(r"C:\Windows\System32\msvcrt.dll")
var_a = 31
lib_2.printf(b"Print int_a = %d\n", var_a)
, DLL, Python ""… . getattr(lib, attr_name)
. : , .
Python:
from ctypes import *
lib = cdll.LoadLibrary(r"C:\Windows\System32\msvcrt.dll")
var_c = 51
print_from_C = getattr(lib, "printf")
print_from_C(b"Print int_c = %d\n", var_c)
:
Print int_c = 51
, . , DLL . , , . , , .
Python
ctypes
. .
1 — Python C, ctypes
.
, — , ? , , printf() :
:
from ctypes import *
lib = CDLL(r"C:\Windows\System32\msvcrt.dll")
printf = lib.printf
int_var = c_int(17)
printf(b"int_var = %d\n", int_var)
str_ = b"Hello, World\n"
str_pt = c_char_p(str_)
printf(str_pt)
print(str_pt)
print(str_pt.value)
:
int_var = 17
Hello, World
c_char_p(2814054827168)
b'Hello, World\n'
, ( , ) value
, .
, int
. restype
. , argtypes
.
, strcat
. .
char *strcat (char *destination, const char *append);
Python:
from ctypes import *
libc = CDLL(r"C:\Windows\System32\msvcrt.dll")
strcat = libc.strcat
strcat.restype = c_char_p
strcat.argtypes = [c_char_p, c_char_p]
str_1 = b"Hello,"
str_2 = b" Habr!"
str_pt = strcat(str_1, str_2)
print(str_pt)
:
b'Hello, Habr!'
DLL. DLL ctypes
, .
DLL
1
DLL , , DLL , — DLL Python. Python x64, , DLL , DLL Python. , x64 Python x64, x32. , .
DLL, , , DllMain
. , .
DLL :
void __declspec(dllexport) SomeFunction(const LPCSTR sometext)
{
MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}
extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
printf("Load DLL in Python\n");
printf("HINSTANCE = %p\n",hinstDLL);
if (lpvReserved)
printf("DLL loaded with implicit layout\n");
else
printf("DLL loaded with explicit layout\n");
return 1;
case DLL_PROCESS_DETACH:
printf("DETACH DLL\n");
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
Python:
from ctypes import *
lib_dll = cdll.LoadLibrary("DLL_example.dll")
str_ = b'Hello, Habr!'
p_str = c_char_p(str_)
lib_dll.SomeFunction(p_str)
SomeFunction
. .

2 — Code Blocks.
DLL_PROCESS_ATTACH
, , Python :
lib_dll = cdll.LoadLibrary("DLL_example.dll")

3 — DLL.
2
DLL Python, , . , Python. main.c
, man.h
main.py
.
DLL :
main.h
#ifndef __MAIN_H__
#define __MAIN_H__
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define DLL_EXPORT __declspec(dllexport)
#ifdef __cplusplus
extern "C"
{
#endif
struct Passport{
char* name;
char* surname;
int var;
};
void DLL_EXPORT SetName(char* new_name);
void DLL_EXPORT SetSurname(char* new_surname);
void DLL_EXPORT SetPassport(Passport* new_passport);
void DLL_EXPORT GetPassport(void);
#ifdef __cplusplus
}
#endif
#endif
main.h
Passport : . , , .
DLL :
main.c
#include "main.h"
#define SIZE_BUF 20
struct Passport passport;
void DLL_EXPORT SetName(char* new_name)
{
printf("SetName\n");
strcpy(passport.name, new_name);
}
void DLL_EXPORT SetSurname(char* new_surname)
{
printf("SetSurname\n");
strcpy(passport.surname, new_surname);
}
void DLL_EXPORT SetPassport(Passport* new_passport)
{
printf("SetPassport\n");
strcpy(passport.name, new_passport->name);
strcpy(passport.surname, new_passport->surname);
passport.var = new_passport->var;
}
void DLL_EXPORT GetPassport(void)
{
printf("GetPassport: %s | %s | %d\n", passport.name, passport.surname, passport.var);
}
extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
printf("Load DLL in Python\n");
passport.name = (char*)malloc(SIZE_BUF * sizeof(char));
passport.surname = (char*)malloc(SIZE_BUF * sizeof(char));
passport.var = 17;
SetName("Default");
SetSurname("Passport");
return 1;
case DLL_PROCESS_DETACH:
free (passport.name);
free (passport.surname);
printf("DETACH DLL\n");
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
DLL_PROCESS_ATTACH
. DllMain
:
GetPassport — passport
.
*SetName(char new_name)** — name
passport
.
*SetSurname(char new_surname)** — surname
passport
.
*SetPassport(Passport new_passport)** — passport
. .
Python.
Python
from ctypes import *
class Passport(Structure):
_fields_ = [("name", c_char_p),
("surname", c_char_p),
("var", c_int)]
lib_dll = cdll.LoadLibrary("DLL_example.dll")
lib_dll.SetPassport.argtypes = [POINTER(Passport)]
lib_dll.GetPassport()
lib_dll.SetName(c_char_p(b"Yury"))
lib_dll.SetSurname(c_char_p(b"Orlov"))
lib_dll.GetPassport()
name = str.encode(("Vasiliy"))
surname = c_char_p((b'Pupkin'))
passport = Passport(name, surname, 34)
lib_dll.SetPassport(pointer(passport))
lib_dll.GetPassport()
, , DLL Python DLL.
:
Load DLL in Python
SetName
SetSurname
GetPassport: Default | Passport | 17
SetName
SetSurname
GetPassport: Yury | Orlov | 17
SetPassport
GetPassport: Vasiliy | Pupkin | 34
DETACH DLL
P.S: , DLL Python. . - — , — . , !
: