2017-07-06 229 views
1

我想爲我的python程序設計一個外部的DLL。現在我可以使用 C++ Visual Studio 2010生成一個後綴爲".pyd"的文件。如果.pyd未與其他由C++生成的.dll文件相關聯,則此python庫可以正常工作。如何啓用pyd在外部C++ dll中調用函數?

不過,現在我需要設計一個.pyd文件,這樣的結構調查:

A.pyd -> 1.dll -> 2.dll

在這些文件1,2是C庫。生產A.pyd時會調用這些庫中的函數。

儘管這個.pyd文件可以通過 VS 2010沒有錯誤地生成,但它無法在Python 3.6中工作。錯誤報告如下:

Traceback (most recent call last): File "<stdin>」,1號線,在<module> 導入錯誤:DLL加載失敗,無法找到目標程序

即使提到1.dll2.dll存儲在的。包含A.pyd同一文件夾中,這個錯誤依然存在。我不知道我怎麼可能讓蟒蛇-C++庫調用函數的基礎上C這些動態鏈接庫。

回答

0

行!現在我找到了執行此操作的正確方法!

包裹DLL

首先,如果DLL (我稱之爲dll-A,你需要調用沒有出口任何功能(你可以使用dumpbin在VS命令檢查導出的函數)你需要包裝原來的dll-A。使用隱式調用來包含dll-A。如果在原來的.h /的.lib聲明的函數,就像這樣:

int func(int a, int b); 

然後,你需要通過這個來創建一個新的dll項目和包裝上面的功能:

.H

extern "C" _declspec(dllexport) int w_func(int a, int b); 

的.cpp

int w_func(int a, int b){ 
    return func(a, b); 
} 

當然,如果dumpbin表明dll-A有可用的導出函數,你可以跳過這一步。

出口這個dll (我稱之爲dll-B,你會得到 'DLL-B' 和它的依賴文件(包括根據文件dll-Adll-A的)之後。

寫的。pyd文件

使用顯式調用來引用dll-B。使用這種方法時,不應該包含任何lib/.h文件,因爲dll-B本身可以爲您提供足夠的接口。您可以通過此方法加載DLL:

.H

typedef int (*func_ptr)(int a, int b); 

的.cpp(名爲Testdll當你寫的.pyd項目功能的一部分)

func_ptr FUNC_API = NULL; 
HINSTANCE h = LoadLibraryA("libdll/dllB.dll"); 
//Certainly! you could set the folder of stored dlls! 
if (h){ 
    FUNC_API = (func_ptr)GetProcAddress(h, "w_func"); 
    //You could load more functions here. 
} 
else{ // If the dll could not be found 
    FreeLibrary(h); 
    return 0x100; 
} 
int errorflag=0; 
if (FUNC_API==NULL){ //Check whether the function is valid. 
    cout << "Could not find: func" << endl; 
    errorflag = errorflag | 0x001; 
} 
//You could check more functions here. 
if (errorflag!=0){ // if any function could not be found. 
    FreeLibrary(h); 
    return 0x100 | errorflag; 
} 
//process functions. 
int a,b,c; 
c = FUNC_API(a,b); 
//Free the lib 
if (h) 
    FreeLibrary(h); 

建立自己的後.pyd,你可以得到你的python數據庫(我稱之爲pyd-C

鏈接與Python

在Python項目的.pyd,你可以用這種方法測試這個文件:

的.py

import pydC 

if __name__ == '__main__': 
    X = pydC.cclass() 
    X.Testdll(); 

然後你就可以發現,功能表現不錯。

注意到你的.pyd應該放在與.py相同的文件夾中。因爲您在libdll/dllB.dll中設置了dll-B,所以應將dll-B放在名爲libdll的文件夾中。但是,因爲dll-B隱含地調用dll-A和其他依賴的dll,所以dll-A和其他文件應位於工作空間文件夾中,即與.py相同的文件夾。

總之,你需要進入工作區文件夾,該文件夾的形成是如下:

./ 
    Test.py 
    pydC.pyd 
    dllA.dll 
    dllA_depended1.dll 
    ... 
    libdll/ 
     dllB.dll 
+0

如果您有任何refered的dll寫的不好,你可能會遇到嚴重的錯誤!這很不幸,因爲你可能無法完善那些依賴於dll的東西。通常,您可以編寫一個C程序來明確引用導出的dll以測試是否可以運行這些dll。如果.exe引發錯誤,那麼在.py中遇到同樣的錯誤幾乎是不可避免的。 –