如何启用pyd在外部C++ dll中调用函数?
我想为我的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.dll
和2.dll
存储在的。包含A.pyd
同一文件夹中,这个错误依然存在。我不知道我怎么可能让蟒蛇-C++库调用函数的基础上C
这些动态链接库。
行!现在我找到了执行此操作的正确方法!
包裹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-A
和dll-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
如果您有任何refered的dll写的不好,你可能会遇到严重的错误!这很不幸,因为你可能无法完善那些依赖于dll的东西。通常,您可以编写一个C程序来明确引用导出的dll以测试是否可以运行这些dll。如果.exe引发错误,那么在.py中遇到同样的错误几乎是不可避免的。 –