我试图为我的python程序设计一个外部DLL
。现在我可以使用 C ++ 和 Visual Studio 2010 生成一个后缀为".pyd"
的文件。如果.pyd
没有附加C ++生成的其他.dll
文件,那么这个python库可以很好地工作。
但是,现在我需要设计一个带有这样结构的.pyd
文件:
A.pyd -> 1.dll
-> 2.dll
其中文件1,2是C库。生成A.pyd
时会调用这些库中的函数。
虽然 VS 2010 可以生成这个.pyd
文件而没有错误,但它无法在python 3.6中运行。错误报告如下:
Traceback (most recent call last):
File "
<stdin>
", line 1, in <module>
ImportError: DLL load failed, could not find the target program.
即使引用的<stdin>
和<module>
存储在包含1.dll
的同一文件夹中,此错误仍然存在。我想知道如何启用 python-C ++ 库来调用基于2.dll
的动态链接库中的函数。
答案 0 :(得分:0)
OK!现在我找到了执行此操作的正确方法!
首先,如果您需要调用的dll (我称之为dll-A
)尚未导出任何功能(您可以在VS命令中使用dumpbin
来检查导出的函数),你需要包装原始的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
)后,您将获得&#39; dll-B&#39;及其依赖文件(包括dll-A
和dll-A
依赖文件。)
使用显式调用来引用dll-B
。使用此方法时,不应包含任何lib / .h文件,因为dll-B
本身可以为您提供足够的接口。您可以通过以下方法加载dll:
·H
typedef int (*func_ptr)(int a, int b);
.cpp(编写.pyd项目时名为Testdll
的函数的一部分)
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项目中,您可以通过以下方法测试此文件:
的.py
import pydC
if __name__ == '__main__':
X = pydC.cclass()
X.Testdll();
然后你会发现这个功能表现得很好。
注意你的.pyd应该与.py所在的文件夹在同一个文件夹中。由于您已在dll-B
中设置了libdll/dllB.dll
,因此dll-B
应放在名为libdll
的文件夹中。但是,由于dll-B
隐式调用dll-A
和其他依赖dll,dll-A
和其他文件应位于工作区文件夹中,即与.py所在的文件夹相同。
简而言之,您需要输入工作区文件夹,文件夹构成如下:
./
Test.py
pydC.pyd
dllA.dll
dllA_depended1.dll
...
libdll/
dllB.dll