您确定这个轻快的库甚至导出 python 绑定吗?我在源代码中看不到任何对它的引用——它甚至似乎没有导入 python 头文件。这肯定可以解释为什么到目前为止您还没有取得太大成功 - 您不能只编译纯 C++ 代码并期望 python 与其交互。
我认为你的第二个 distutils 示例最接近正确 - 它显然正在编译内容并进入链接器阶段,但随后你遇到了这个错误。该错误只是意味着它找不到名为 initbrisk 的函数,我猜测该函数将是该模块的顶级 init 函数。这再次表明您正在尝试从不适合的代码编译 python 模块。
如果你想自己将 C++ 代码包装在 python 包装器中,你可以看看关于编写 c/c++ 扩展的官方文档 http://docs.python.org/extending/extending.html。或者你可以看看提升::蟒蛇 http://www.boost.org/doc/libs/1_49_0/libs/python/doc/, SIP http://www.riverbankcomputing.co.uk/software/sip/intro or shiboken http://www.pyside.org/docs/shiboken/它试图在某种程度上(或完全)自动化从 C++ 代码创建 python 扩展的过程。
编辑:由于您似乎已经付出了相当大的努力来自己解决问题,并且发布了一个很好的问题,因此我决定就如何去做这件事给出更详细的答复。
使用 boost::python 包装 C++ 库的快速教程
就我个人而言,我只使用过 boost::python 来完成类似的事情,所以我将尝试为您提供一个关于如何做到这一点的很好的总结。我将假设您使用的是 Visual C++ 2010。我还将假设您安装了 32 位版本的 python,因为我相信 boost pro 库仅提供 32 位二进制文件。
安装升压
首先,您需要获取 boost 库的副本。最简单的方法是从以下位置下载安装程序Boost Pro 网站 http://www.boostpro.com/download/。这些应该安装在 Windows 上使用 boost c++ 库所需的所有头文件和二进制文件。记下这些文件的安装位置,因为稍后您将需要它们 - 最好安装到其中没有空格的路径。为简单起见,我假设您将这些文件放在 C:\boost 中,但您可以将其替换为您实际使用的路径。
或者,您可以按照这些说明 http://www.boost.org/doc/libs/1_49_0/more/getting_started/windows.html#or-build-binaries-from-source从源头打造提升。我不是 100% 确定,但情况可能是这样need这样做是为了获得与您安装的 python 版本兼容的 boost::python 版本。
设置视觉工作室项目
接下来,您需要为 brisk.pyd 设置一个 Visual Studio 项目。如果您打开 Visual Studio,请转到“新建”->“项目”,然后找到“Win32 项目”选项。设置您的位置等,然后单击“确定”。在出现的向导中选择 DLL 项目类型,然后勾选空项目复选框。
现在您已经创建了项目,您需要设置包含和库路径以允许您使用 python、boost::python 和 brisk.lib 文件。
在 Visual Studio 解决方案资源管理器中,右键单击您的项目,然后从出现的菜单中选择属性。这应该会打开您的项目的属性页。转到链接器 -> 常规部分并查找其他库目录部分。您需要用到的路径填写此内容.lib
boost、python 和你的文件brisk_static.lib
。一般来说,这些可以在lib
(or libs
) 的子目录
无论您在何处安装了库。路径用分号分隔。我在下面附上了我的设置的屏幕截图:
接下来,您需要让 Visual Studio 链接到 .lib 文件。这些部分可以在属性的链接器 -> 输入部分的附加依赖项字段中找到。这又是一个以分号分隔的列表。您应该需要添加 python 库(在我的例子中是python27.lib
但这会因版本而异)和brisk_static.lib
。这些不需要您在上一阶段添加的完整路径。再次,这是一个屏幕截图:
You may还需要添加 boost_python 库文件,但我thinkboost 使用一些头文件魔法来省去你的麻烦。如果我不正确,那么请查看您的 boost 库路径中是否有一个名为类似于的文件boost_python-vc100-mt.lib
并将其添加进去。
最后,您需要设置包含路径以允许您的项目包含相关的 C++ 头文件。要使相关设置显示在项目属性中,您需要将 .cpp 文件添加到项目中。右键单击解决方案资源管理器中的源文件文件夹,然后去添加新项目。选择一个 C++ 文件 (.cpp) 并将其命名为 main.cpp(或任何您想要的名称)。
接下来,返回项目属性并转到 C/C++ -> 常规。在附加库目录下,您需要添加 brisk、python 和 boost 的包含路径。同样,分隔符用分号,这里还是一个屏幕截图:
我怀疑您可能需要更新这些设置以包括 opencv2 和 agast 库,但我将把它作为一项任务留给您来解决 - 它应该是大致相同的过程。
使用 boost::python 包装现有的 C++ 类。
现在出现了稍微棘手的一点 - 实际上编写 C++ 将你的 brisk 库包装在 boost python 中。你可以找到这方面的教程here http://www.boost.org/doc/libs/1_49_0/libs/python/doc/tutorial/doc/html/index.html但我也会尝试稍微回顾一下。
这将发生在main.cpp
您之前创建的文件。首先,在文件顶部添加您需要的相关包含语句:
#include <brisk/brisk.h>
#include <Python.h>
#include <boost/python.hpp>
接下来,您需要声明您的 python 模块。我假设您希望将其称为“轻快”,因此您可以执行以下操作:
BOOST_PYTHON_MODULE(brisk)
{
}
这应该告诉 boost::python 创建一个名为的 python 模块brisk
.
接下来,只需检查要包装的所有类和结构并用它们声明 boost python 类。类的声明应全部包含在 brisk.h 中。您应该只包装类的公共成员,而不是任何受保护或私有成员。作为一个简单的例子,我在这里完成了几个结构:
BOOST_PYTHON_MODULE(brisk)
{
using namespace boost::python;
class_< cv::BriskPatternPoint >( "BriskPatternPoint" )
.def_readwrite("x", &cv::BriskPatternPoint::x)
.def_readwrite("y", &cv::BriskPatternPoint::y)
.def_readwrite("sigma", &cv::BriskPatternPoint::sigma);
class< cv::BriskScaleSpace >( "BriskScaleSpace", init< uint8_t >() )
.def( "constructPyramid", &cv::BriskScaleSpace::constructPyramid );
}
在这里,我包装了 cv::BriskPatternPoint 结构和 cv::BriskScaleSpace 类。一些快速解释:
class_< cv::BriskPatternPoint >( "BriskPatternPoint" )
告诉 boost::python 声明一个类,使用cv::BriskPatternPoint
C++ 类,并将其公开为BriskPatternPoint
在Python中。
.def_readwrite("y", &cv::BriskPatternPoint::y)
添加一个可读可写的属性BriskPatternPoint
班级。该属性名为 y,并将映射到BriskPatternPoint::y
c++ 字段。
class< cv::BriskScaleSpace >( "BriskScaleSpace", init< uint8_t >() )
这次声明了另一个类BriskScaleSpace
而且还提供了一个接受 uint8_t (一个无符号字节 - 它应该只映射到 python 中的整数,但我会小心不要传入大于 255 个字节 - 我不知道会发生什么)的构造函数情况)
下列.def
line 只是声明一个函数 - boost::python 应该(我认为)能够自动确定函数的参数类型,因此您不需要提供它们。
可能值得注意的是,我实际上并没有编译任何这些示例 - 它们很可能根本不起作用。
不管怎样,为了让这个在Python中完全工作,应该对你想要从Python访问的每个结构、类、属性和函数做类似的事情——这可能是一项相当耗时的任务!
如果你想看看另一个实际的例子,我做了这里 https://raw.github.com/obmarg/syncro/develop/Syncro%20Server/libsyncro/pysyncro/pysyncro.cpp结束这个班 https://github.com/obmarg/syncro/blob/develop/Syncro%20Server/libsyncro/include/libsyncro/connection.h
构建和使用扩展
Visual Studio 应该负责构建扩展 - 然后使用它只是获取 .DLL 并将其重命名为 .pyd(您可以让 VS 为您完成此操作,但我将把它留给您)。
然后你只需要将 python 文件复制到 python 路径上的某个位置(site-packages
例如),导入并使用它!
import brisk
patternPoint = brisk.BriskPatternPoint()
....
不管怎样,我花了一个小时左右的时间来写这篇文章——所以我就到这里为止。如果我遗漏了任何内容或者有任何不清楚的地方,我深表歉意,但我主要是凭记忆做的。希望对您有所帮助。如果您需要澄清任何内容,请发表评论,或提出其他问题。