Python'dan bir DLL dosyasını nasıl kullanabilirim?


186

İçeriden bir DLLdosyayı kullanmanın en kolay yolu nedir Python?

Özellikle, bu nasıl yapılabilir olmadan herhangi bir ek sarıcı yazma C++işlevsellik ortaya çıkarmak için kod Python?

Yerel Pythonişlevsellik, üçüncü taraf bir kitaplık kullanmaya kıyasla çok tercih edilir.


@Remuze yanlış soruyu veya etiketi yanlış cevapla mı etiketlediniz? İkisi de python, ama onları benzer bulmanız için hiçbir neden göremiyorum (ve geçmişin bir noktasında daha yakın olmadığından emin olmak için düzeltme geçmişini kontrol ettim)
Foon

@ foon hmmm evet üzgünüm, başka bir soruyu yinelenen olarak işaretlemek ve bunu koymak istedim :) Sanırım ne kadar benzer olduklarını gösteriyor!
Trev Davies

Yanıtlar:


154

Kullanım kolaylığı için, ctypes gidilecek yoldur.

Aşağıdaki ctypes örneği yazdığım gerçek koddan (Python 2.5). Bu, sorduğunuz şeyi yapmak için bulduğum en kolay yol oldu.

import ctypes

# Load DLL into memory.

hllDll = ctypes.WinDLL ("c:\\PComm\\ehlapi32.dll")

# Set up prototype and parameters for the desired function call.
# HLLAPI

hllApiProto = ctypes.WINFUNCTYPE (
    ctypes.c_int,      # Return type.
    ctypes.c_void_p,   # Parameters 1 ...
    ctypes.c_void_p,
    ctypes.c_void_p,
    ctypes.c_void_p)   # ... thru 4.
hllApiParams = (1, "p1", 0), (1, "p2", 0), (1, "p3",0), (1, "p4",0),

# Actually map the call ("HLLAPI(...)") to a Python name.

hllApi = hllApiProto (("HLLAPI", hllDll), hllApiParams)

# This is how you can actually call the DLL function.
# Set up the variables and call the Python name with them.

p1 = ctypes.c_int (1)
p2 = ctypes.c_char_p (sessionVar)
p3 = ctypes.c_int (1)
p4 = ctypes.c_int (0)
hllApi (ctypes.byref (p1), p2, ctypes.byref (p3), ctypes.byref (p4))

ctypesMalzeme (her Cı-tip veri türleri vardır int, char, short, void*, ve benzeri) ve değer ya da referans ile bu geçebilir. Örneğim bunu yapmasa da belirli veri türlerini döndürebilir (HLL API, başvuru ile iletilen bir değişkeni değiştirerek değerleri döndürür).


Yukarıda gösterilen spesifik örnek açısından, IBM'in EHLLAPI'si oldukça tutarlı bir arayüzdür.

Tüm çağrılar dört boş işaretçi (EHLLAPI dönüş kodunu dördüncü parametre aracılığıyla geri gönderir, bu şekilde bir işaretçi , dönüş türü olarak intbelirtirken int, güvenli bir şekilde yok sayabilirim) burada IBM'in belgelerine göre . Başka bir deyişle, işlevin C varyantı şu şekildedir:

int hllApi (void *p1, void *p2, void *p3, void *p4)

Bu ctypes, EHLLAPI kitaplığının sağladığı her şeyi yapabilen tek ve basit bir işlev sağlar, ancak diğer kitaplıkların ctypeskitaplık işlevi başına ayrı bir işleve ihtiyaç duyması muhtemeldir .

Dönüş değeri WINFUNCTYPEbir işlev prototipidir, ancak yine de daha fazla parametre bilgisi ayarlamanız gerekir (türlerin üstünde ve üstünde). Her bir demet hllApiParams"yön" (1 = giriş, 2 = çıkış vb.), Parametre adı ve varsayılan değere sahiptir - ayrıntılar için ctypesdoco'ya bakın

Prototip ve parametre bilgilerine sahip olduktan sonra hllApi, işlevi çağırmak için "çağrılabilir" bir Python oluşturabilirsiniz . Sadece (gerekli değişken oluşturmak p1yoluyla p4benim durumumda) ve onlarla birlikte işlevini çağırın.


1
Merhaba, birisi burada cevap verdikten sonra uzun zaman alabilir, ancak bu programı tam olarak programım için çalıştıracak bir şey bilmek istedim. Bana bunun "HLLAPI" ne olduğunu söyleyebilir misiniz? Ayrıca, benim dll "void BoxProperties (çift L, çift H, çift W, çift & A, çift & V);"; Çalıştırmak için yukarıdaki kodda ne gibi değişiklikler yapmam gerektiğini önerebilir misiniz? Şerefe.
Neophile

4
Tam olarak ne yapar hllApiParams? Bu tuple'lerin anlamı nedir? Bu örnekteki bazı şeyleri belgelerle eşleştirmek zordur.
Jonathon Reinhart

1
@JonathonReinhart, altta bazı metin ile belirli bir örnek ettim. Umarım, bu biraz daha iyi açıklar. Değilse, bana bildirin ve tekrar deneyeceğim :-)
paxdiablo

1
mükemmel cevap, 6 yıl sonra çok yardımcı olur :) Ben yapabilirdim eğer +100 koymak olurdu!
Albay Beauvel

1
Bu, yeni başlayanlar açısından yeni bir kafa karıştırıcıdır.
DuckPuncher

69

Bu sayfada , bir DLL dosyasından işlevleri çağırmanın çok basit bir örneği vardır.

Bütünlük için ayrıntıları burada açıklayın:

Python'da bir DLL işlevini çağırmak çok kolaydır. İki işlevi ile kendi kendine yapılan bir DLL dosyası var: addve subiki argüman alır.

add(a, b)iki sayının eklenmesini döndürür iki sayının çıkarılmasını
sub(a, b)döndürür

DLL dosyasının adı "demo.dll" olacaktır.

Programı:

from ctypes import*
# give location of dll
mydll = cdll.LoadLibrary("C:\\demo.dll")
result1= mydll.add(10,1)
result2= mydll.sub(10,1)
print "Addition value:"+result1
print "Substraction:"+result2

Çıktı:

Addition value:11
Substraction:9


2
Bu cevaptaki bağlantı koptu.
Kaliber64

10
Bağlantı sizin için çalışmazsa endişelenmeyin, doğrudan kopyala yapıştırır. Hiçbir bilgi eksik değil.
bataklık


6

Belki de Dispatch:

from win32com.client import Dispatch

zk = Dispatch("zkemkeeper.ZKEM") 

Burada zkemkeeper sistemde kayıtlı bir DLL dosyasıdır ... Bundan sonra, işlevlere sadece onları çağırarak erişebilirsiniz:

zk.Connect_Net(IP_address, port)

Bu zkemkeeper.ZKEM üzerinde çalışıyorum, python'da gerçek zamanlı olayları nasıl alabileceğimi biliyor musunuz?
Sam Ziggler

4

Bir DLL oluşturma ve cytpes kullanarak Python altında bağlama

Nasıl bir yapı üzerinde tam olarak çalıştı örnek sunmak shared libraryve altında kullanarak Pythonvasıtasıyla ctypes. WindowsDavayı ele alıyorum ve ilgileniyorum DLLs. İki adım gereklidir:

  1. DLL'i komut satırından veya IDE'den Visual Studio'nun derleyicisini kullanarak oluşturun;
  2. Cytpes kullanarak Python altında DLL bağlayın.

Paylaşılan kütüphane

shared libraryBen düşünün şudur ve bulunan testDLL.cppdosyanın. Tek işlev testDLLsadece bir alır intve yazdırır.

#include <stdio.h>

extern "C" {

__declspec(dllexport)

void testDLL(const int i) {
    printf("%d\n", i);
}

} // extern "C"

DLL'i komut satırından oluşturma

Komut satırından bir DLLile oluşturmak içinVisual Studio

"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\vsdevcmd"

dahil etme yolunu ayarlamak ve ardından

cl.exe /D_USRDLL /D_WINDLL testDLL.cpp /MT /link /DLL /OUT:testDLL.dll

DLL oluşturmak için.

DLLIDE'den bina

Alternatif olarak, aşağıdaki gibi DLLkullanılarak inşa edilebilir Visual Studio:

  1. Dosya -> Yeni -> Proje;
  2. Yüklü -> Şablonlar -> Visual C ++ -> Windows -> Win32 -> Win32Project;
  3. Sonraki;
  4. Uygulama türü -> DLL;
  5. Ek seçenekler -> Boş proje (seç);
  6. Ek seçenekler -> Önceden derlenmiş başlık (seçimi kaldır);
  7. Proje -> Özellikler -> Yapılandırma Yöneticisi -> Aktif çözüm platformu: x64;
  8. Proje -> Özellikler -> Configuration Manager -> Etkin çözüm yapılandırması: Sürüm.

DLL Python altında bağlama

Python altında aşağıdakileri yapın

import os
import sys
from ctypes import *

lib = cdll.LoadLibrary('testDLL.dll')

lib.testDLL(3)

Python paketindeki DLL dosyası nedir? Nasıl erişirim?
decadenza

3

ctypes kullanması en kolay şey olacaktır, ancak (mis) kullanarak Python çökmeye neden olur. Hızlı bir şekilde bir şeyler yapmaya çalışıyorsanız ve dikkatli iseniz, bu harika.

Boost Python'a göz atmanızı öneririm . Evet, bazı C ++ kodu yazmanızı ve bir C ++ derleyicisine sahip olmanızı gerektirir, ancak aslında kullanmak için C ++ öğrenmeniz gerekmez ve Microsoft'tan ücretsiz (birada olduğu gibi) bir C ++ derleyicisi alabilirsiniz .


0

DLL COM türünde ise, pythonnet kullanabilirsiniz.

pip install pythonnet

Ardından python kodunuzda aşağıdakileri deneyin

import clr
clr.AddReference('path_to_your_dll')

daha sonra DLL'deki sınıfa göre bir nesne başlatın ve içindeki yöntemlere erişin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.