从嵌入的Python代码中加载DLL
我遇到的问题是这样的:
我在Windows XP上用C语言和MS Visual Studio 10.0开发代码,需要嵌入Python来做一些绘图、文件管理和其他事情。我之前遇到过sys.path找不到我的纯Python模块的问题,但我通过修改PYTHONPATH解决了这个问题。
现在,我的问题是让Python找到一些模块所需的动态库。具体来说,我想把一个文件夹压缩成一个同名的bzip2压缩文件。
在普通的Python命令提示符下,这个操作可以正常工作:
import tarfile
tar=tarfile.open('Code.tar.bz2','w:bz2')
tar.add('Code',arcname='Code')
tar.close()
但是当我从我的C代码中调用这个操作时,就出现了这个错误:
Traceback (most recent call last):
File "<string>", line 4, in <module>
File "D:\My_Documents\Code\ScrollModel\trunk\PythonCode.py", line 20, in Colle
ctFiles
tar=tarfile.open(os.path.join(runPath,'CODE.tar.bz2'),'w:bz2')
File "c:\Python26\lib\tarfile.py", line 1671, in open
return func(name, filemode, fileobj, **kwargs)
File "c:\Python26\lib\tarfile.py", line 1737, in bz2open
raise CompressionError("bz2 module is not available")
tarfile.CompressionError: bz2 module is not available
我怀疑这个问题和嵌入Python文档第5.6节中描述的问题类似,但有点难以判断。顺便说一下,如果我执行
Py_Initialize();
PyRun_SimpleString("import ssl\n");
Py_Finalize();
这个操作也不行,结果是出现了ImportError错误。
有没有人遇到过类似的问题?我是不是漏掉了什么重要的东西?
3 个回答
我之前也遇到过类似的问题,关于Boost C++的DLL。任何外部的DLL都需要放在DLL搜索路径里。
根据我的经验,PYTHONPATH会影响Python模块(在Python中使用import语句时,最终会调用LoadLibrary),而构建选项和这个没有关系。
当你加载一个DLL时,Windows并不关心这个进程是什么。换句话说,Python遵循的DLL加载规则和记事本是一样的。你可以通过把缺失的DLL复制到你的Python扩展所在的同一个文件夹,或者放到你的路径中的某个文件夹,来确认你遇到的是Windows路径的问题。
要找出其他可执行文件或DLL需要哪些DLL,只需用DependencyWalker打开那个DLL或EXE文件就可以了。它还有一个“Profile”菜单,可以让你运行你的应用程序,并观察它是如何搜索和加载DLL的。
嘿,我之前问过一个类似的问题,我的操作系统是Linux。
在编译C文件的时候,需要加上这个选项:$(python-config --cflags --ldflags)
,就像这样:
gcc test.c $(python-config --cflags --ldflags) -o test
我觉得在Windows上,你也可以检查一下python-config
这个选项,希望这对你有帮助!
试试这个,这在我的电脑上可以运行。
首先,在Visual Studio 2010中创建一个简单的Windows控制台应用程序(在向导中去掉预编译头的选项)。然后把生成的代码替换成下面的代码:
#include <Python.h>
int main(int argc, char *argv[]) {
Py_Initialize();
PyRun_SimpleString("import ssl \n"
"for f in dir(ssl):\n"
" print f \n" );
Py_Finalize();
return 0;
}
确保PYTHONHOME设置为类似c:\Python这样的路径...
- 把C:\Python\Include添加到包含路径中
- 把C:\Python\Libs添加到库路径中
- 把python26.lib添加到链接器输入中(根据你的Python版本进行调整)
构建项目。然后从任何地方运行,你应该能看到ssl模块的内容列表。
我也尝试过用Mingw。用同样的文件,使用下面的命令行进行构建:
gcc -Wall -o test.exe embeed.c -I%PYTHONHOME%\Include -L%PYTHONHOME%\libs -lpython26