在MinGW中编译Boost.Python

 

有时候,我写程序纯粹是为了好玩。比如,对于Python和Boost。身边很多朋友,看我兴致勃勃的学习它,会常看外星人一样地问我:“这有什么用吗?”

我开始觉得很郁闷,后来就学会一笑处之。何必要去争呢?为了生存而生活,并不是什么错误的态度,不过,抱这样态度的朋友,不可能向他们说清楚,这种生活的乐趣。如果只­是为了谋生,我就应该一辈子安心于使用RAD。但是,我喜欢C++,喜欢Python。这样的语言,可以让我得到乐趣。虽然我可能永远也成不了Bjarne,但是,我可以做一个快乐的人,这不是很好吗?

做为一个纯粹的C++“爱好者(而非职业C++程序员)”,我很少使用VC。很长时间里,我一直在用内置GCC的Dev C++。后来,又专门下载了一个MinGW,集成在Dev C++中,做为编译器内核。不知道CSDN上有多少像我这样的“玩家”。不过,从前一段时间论坛上的贴子来看,所有像我这样使用MinGW+Python+Boost的朋友,都遇到一个很头痛的问题:Boost.Python不能安装。

这个问题的具体表现在于,用MinGW编译Boost.Python时,会提示找不到若干定义,最后归为6个以上的错误。具体的数目好像会有不同。我的机器上通常会是6个,而有一位朋友,他的机器编译时一般是9个错误。这个问题困扰了我们这些C++菜鸟很久。因为同样的问题在VC上就不会出现。最后,一个偶然的机会,我发现,其实,这个问题一点也不神秘:在Boost.Pyhton的编译过程中,需要调用一个静态库pythonxx.lib(xx是两位数字,视Python的版本而定,我这里是Python22.lib)。而Python的Windows版本,是使用VC编译的!所以在VC中,不会出现这样的问题。而MinGW通常不能正确的识别这个VC编译出的静态库。同样的问题不只出在编译Boost.Python。只要使用安装版的Python与MinGW集成使用,都会出现这个问题。

怎么办?用MinGW重编译Python源码?这听起来是个好主意,从根本上解决问题。不过让我很失望的是,在我这里,用Cygwin还可以正确编译Python源码,MinGW就不行。大概是因为我的方法不当。如果哪位高人了解,还请指教。而从另一个角度看,只要能得到一个MinGW编译的lib文件就可以。而这个方法,其实在Python的文档中已经提到了--虽然没有说与Boost.Python有关,但是,这的确是最简单的方法。下面我把它整理出来,介绍一下。

1、我们需要一个工具,用来生成Python22.lib的Def文件。这个Def,其实是从Python22.DLL(动态链接库是语言及编译器无关的)得到的。先下载PExports 0.42h( http://starship.python.net/crew/kernr/mingw32/pexports-0.42h.zip。解压缩后可以在Bin目录中找到一个可执行文件pexports.exe。为了方便,我们可以把这个目录加到path中;

2、在系统目录中找到python22.dll,把它复制到一个单独的目录中(我把它放在我的python/DLLs里,为的是一并处理掉其它的DLL);

3、在命令行模式下,转到放置python22.dll的目录,执行:pexports python22.dll >python22.def;

4、现在,我们在这个目录下,可以找到python22.def,用文本编辑器打开它,会看到在编译Boost.Python时找不到的那些定义,就在其中;

5、使用GCC的附带工具,生成静态文件,现在执行:dlltool --dllname python22.dll --def python22.def --output-lib python22.lib。

我们现在就可以在这个目录下,找到梦寐以求的python22.lib了。

用同样的方法,我生成了MinGW版本的其它若干个lib文件,如zlib.lib,parser.lib等。现在,把它们放在一个新的目录中(也可以在生成它们时,直接指定一个目录)。把Boost.Python所需要的libs目录变量设定为这个目录,就可以正确编译Boost.python了!

欢迎所有使用MinGW的朋友来到Boost.Python的世界!这个时候,大概你已经在试验Boost的示例,甚至自己开始用Boost扩展Python了吧。

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论
为了方便大家使用MinGWGCC)+_boost.python,特意只做了三个dll,可以很方便地将c++代码转为python模块. libboost_python-mgw45-1_49.dll libboost_python-mgw45-d-1_49.dll python27.dll 这三个文件我已放资源里面,大家可以下载. 下面说说使用方法: 第一步:编写一个hello_ext.cpp的c++源文件 #include <boost/python.hpp> // 第一行必须是#include <boost/python.hpp> // 否则会留下一点小问题 #include <vector> // 输出字符串 char const* greet() { return "hello, world"; } // 实现两个数字相加 int add(int x, int y) { return x + y; } // 打印vector的函数 void vprint() { std::vector<int>myvector; for (int i = 1; i <= 5; i++) { myvector.push_back(i); } std::vector<int>::iterator it; std::cout << "myvector contains:"; for (it = myvector.begin(); it < myvector.end(); it++) { std::cout << " " << *it; } std::cout << std::endl; } // 定义python模块的接口文件 BOOST_PYTHON_MODULE(hello_ext) { // hello_ext为导出python模块的名字 using namespace boost::python; def("greet", greet); // 导出函数greet def("add", add); // 导出函数add def("vprint", vprint); // 导出函数vprint } 将上面的文件一定要保存为utf-8的格式(使用记事本保存的时候就可以选择),不推荐Ansi格式! 然后就可以使用下面的命令编译python模块了: g++ -o hello_ext.pyd hello_ext.cpp -shared libboost_python-mgw45-1_49.dll python27.dll 也可以使用如下的命令,编译debug版本 g++ -o hello_ext.pyd hello_ext.cpp -shared libboost_python-mgw45-d-1_49.dll python27.dll 运行上面的命令之前,请确保hello_ext.cpp,libboost_python-mgw45-1_49.dll,libboost_python-mgw45-d-1_49.dll和 python27.dll同一个目录. hello_ext.pyd就是python能直接使用的动态链接库,windows一般以dll为后缀,而python只承认pyd文件. 下面来测试一下: import hello_ext print hello_ext.greet() print hello_ext.add(1,3) hello_ext.vprint() 输出为: hello, world 4 myvector contains: 1 2 3 4 5 看,成功了! ============================================================================= 使用g++编译常见的问题就是找不到文件<boost/python.hpp>和pyconfig.h等文件. 这些文件其实boost的目录下面和C:\Python27\include目录. 为了使用方便,将整个\boost_1_49_0\boost\目录复制到MinGw的include目录下面; 将C:\Python27\include目录下的文件全部复制到MinGw的include目录下面即可. 如果不想复制,也可以给g++设置-L参数 -LC:\boost\include\boost_1_49_0\ 和-LC:\Python27\include, 不过每次都这样,还是麻烦,不如复制一下彻底解决! 发布hello_ext.pyd的时候,由于是动态链接库,所以不要忘了libboost_python-mgw45-1_49.dll, libboost_python-mgw45-d-1_49.dll和 python27.dll也要一起发布!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

ccat

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值