python与c++交互学习入门之5
这次讲讲,如何扩展c++库。通过boost.python把c++库编译成python能够调用的dll。
通过上一次的教程后,大家都应该会使用boost.python了。把c++程序编译成pyd文件。由于c++有很多特性,所以,如果你的程
序用了很多的c++特性的话,那么你必须做很多工作了。像虚拟函数,函数重载,继承,默认值等等。具体如何转化,请参
boost.python的文档了。
这几天尝试着把c++程序库编译成python可调用的dll,不知道为什么一直不可用。。很是郁闷。老是显示如下的错误:
- Traceback (most recent call last):
- File "<pyshell#3>", line 1, in <module>
- import pydll
- ImportError: No module named pydll
意思是说找不到dll。我把dll都copy到python/dlls下了还是不行,而且我确定python的sys.path包含了python/dlls目录了。
很是不解。网上也很难找到资料,google了很长时间找不到有用的资料,好像中文方面的资料很少的。今天尝试了一下google
英文资料,终于有了新的发现:
http://mail.python.org/pipermail/c++-sig/2007-February/011971.html
You are using Python2.5. In this version of Python you have to have file extension to be "pyd" - sge.pyd
--
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/
有人碰到的问题跟我的是一样的。后面那个Roman回答了一下,是文件扩展名的问题!!!为什么不支持dll呢?不解。回去试
了一下把后缀名改了就成功了。。。why???
下面来看一下我的那个简单的例子:
这个例子来自于网上,
http://www.vckbase.com/document/viewdoc/?id=1540
C++ 扩展和嵌入 Python
作者:胡金山
源码下载地址:http://www.vckbase.com/code/downcode.asp?id=2777
这是一个非常简单的dll工程。给python提供了一个函数static PyObject* Recognise(PyObject *self, PyObject *args)。
1、不使用boost.python库来直接构建dll
接下来,我们来用C++为Python编写扩展模块(动态链接库),并在Python程序中调用C++开发的扩展功能函数。生成一个取名为
pyUtil的Win32 DLL工程,除了pyUtil.cpp文件以外,从工程中移除所有其它文件,并填入如下的代码:
-
- #ifdef PYUTIL_EXPORTS
- #define PYUTIL_API __declspec(dllexport)
- #else
- #define PYUTIL_API __declspec(dllimport)
- #endif
-
- #include<windows.h>
- #include<string>
- #include<Python.h>
- BOOL APIENTRY DllMain( HANDLE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
- {
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
- }
- std::string Recognise_Img(const std::string url)
- {
-
- return "从dll中返回的数据... : " +url;
- }
- static PyObject* Recognise(PyObject *self, PyObject *args)
- {
- const char *url;
- std::string sts;
- if (!PyArg_ParseTuple(args, "s", &url))
- return NULL;
- sts = Recognise_Img(url);
- return Py_BuildValue("s", sts.c_str() );
- }
- static PyMethodDef AllMyMethods[] = {
- {"Recognise", Recognise, METH_VARARGS},
- {NULL, NULL}
- };
- extern "C" PYUTIL_API void initpyUtil()
- {
- PyObject *m, *d;
- m = Py_InitModule("pyUtil", AllMyMethods);
- d = PyModule_GetDict(m);
- }
Python代码中调用这个动态链接库: (记得把dll的扩展名改为.pyd,另外dll的路径要能够被检索到)
- import pyUtil
- result = pyUtil.Recognise("input url of specific data")
- print "the result is: "+ result
2、使用boost.python库来构建dll
用C++为Python写扩展时,如果您愿意使用Boost.Python库的话,开发过程会变得更开心J,要编写一个与上述pyUtil同样功能的动态链接库,只需把文件内容替换为下面的代码。当然,编译需要boost_python.lib支持,运行需要boost_python.dll支持。
- #include<string>
- #include <boost/python.hpp>
- using namespace boost::python;
- #pragma comment(lib, "boost_python.lib")
- std::string strtmp;
- char const* Recognise(const char* url)
- {
- strtmp ="从dll中返回的数据... : ";
- strtmp+=url;
- return strtmp.c_str();
- }
- BOOST_PYTHON_MODULE(pyUtil)
- {
- def("Recognise", Recognise);
- }
可以非常明显地看到,用了boost.python库之后,简单了很多。因为boost.python为你做了很多的事情。。恩。好像没有讲很多有用的东西,光顾着讲了,呵呵。。。我也还在继续学习之中。下次写点什么呢?继续学习了哦
原文:http://www.cppblog.com/jacky2019/archive/2007/05/17/24269.html
(jacky2019) |