如何从C/C ++源代码获得Windows的Python .Pyd? (更新:现在在python中轻快,以防万一您想要的)[英] How to get a python .pyd for Windows from c/c++ source code? (update: brisk now in Python in case that's what you want)

本文是小编为大家收集整理的关于如何从C/C ++源代码获得Windows的Python .Pyd? (更新:现在在python中轻快,以防万一您想要的)的处理方法,想解了如何从C/C ++源代码获得Windows的Python .Pyd? (更新:现在在python中轻快,以防万一您想要的)的问题怎么解决?如何从C/C ++源代码获得Windows的Python .Pyd? (更新:现在在python中轻快,以防万一您想要的)问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

如何从C/C ++扩展源代码到Windows的PYD文件(或我可以导入Python的其他项目)?

编辑: 我想使用的特定库(Brisk)包含在 opencv 2.4.3因此,我暂时对此技能的需求消失了.如果您来这里寻找轻快的人,这是一个简单的 python demo in python demo 我发布了. p>


我有 brisk brisk source code(下载)我想在我的python应用程序中构建和使用.我到达了一个brisk.pyd文件...但是是0字节.如果有一种更好的/替代方法来瞄准Brisk.pyd文件,那么我当然也对此开放.

编辑: 请忽略下面我最初的问题中的所有尝试,然后查看我的答案,这是Obmarg的详细演练

使我成为可能的

我要去哪里?

  1. distutils没有库路径:首先,我尝试像distutils和以下设置一样构建源).轻源代码的结构在此问题的底部供参考.

    from distutils.core import setup, Extension
    module1 = Extension('brisk',
        include_dirs = ['include', 'C:/opencv2.4/build/include', 'C:/brisk/thirdparty/agast/include'],
        #libraries = ['agast_static', 'brisk_static'],
        #library_dirs = ['win32/lib'],
        sources = ['src/brisk.cpp'])
    setup (name = 'BriskPackage',
        ext_modules = [module1])
    

    立即给了我以下行和 0字节Brisk.pyd 在构建文件夹中的某个地方.如此接近?

    running build
    running build_ext
    
  2. distutils用图书馆路径:刮擦尝试.因此,我添加了上述设置中评论的两个库线.似乎可以按照我的链接错误进行操作:

    creating build\lib.win32-2.7
    C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\link.exe /DLL /nologo /INCREMENTAL:NO /LIBPATH:win32/lib /LIB
    PATH:C:\Python27_32bit\libs /LIBPATH:C:\Python27_32bit\PCbuild agast_static.lib brisk_static.lib /EXPORT:initbrisk build
    \temp.win32-2.7\Release\src/brisk.obj /OUT:build\lib.win32-2.7\brisk.pyd /IMPLIB:build\temp.win32-2.7\Release\src\brisk.
    lib /MANIFESTFILE:build\temp.win32-2.7\Release\src\brisk.pyd.manifest
    LINK : error LNK2001: unresolved external symbol initbrisk
    build\temp.win32-2.7\Release\src\brisk.lib : fatal error LNK1120: 1 unresolved externals
    error: command '"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\link.exe"' failed with exit status 1120
    
  3. 不受控制的Flailing:我认为也许需要构建库,所以我使用CMAKE + MINGW -MINGW + MINGW + VC ++ Express进行了速成课程(很多崩溃),如下:

    • cmake gui:来源:c:/brisk,build:c:/brisk/build
    • cmake gui:为Visual Studio配置10
    • cmake gui:使用默认选项并生成(cmake_backwards_compatibility,cmake_install_prefix,exputable_output_path,library_output_path,library_output_path)
    • vc ++ express 10:更改以释放和构建由Cmake生成的解决方案,并获得大约20页的非关键警告,然后所有成功.注意 - 没有生成DLL.它确实生成了以下与下载包含的库相似的库:

      win32/lib/Release/
          agast_static.lib
          brisk_static.lib
      
  4. 进一步的弹力.

相关的Brisk源文件结构:

build/ (empty)
include/brisk/
    brisk.h
    hammingsse.hpp
src
    brisk.cpp
    demo.cpp
thirdparty/agast/
    include/agast/
        agast5_8.h ....
        cvWrapper.h
    src/
        agast5_8.cc ...
    CMakeLists.txt
win32/
    bin/
        brisk.mexw32
        opencv_calib3d220.dll ...
    lib/
        agast_static.lib
        brisk_static.lib
CMakeLists.txt
FindOpenCV.cmake
Makefile

推荐答案

您确定这个轻快的库甚至导出Python绑定吗?我在源代码中看不到任何引用 - 它甚至似乎都不会导入Python标头文件.这肯定可以解释为什么您到目前为止还没有取得太大的成功 - 您不能仅编译普通的C ++代码,并期望Python与之交互.

我认为您的第二个distutils示例最接近纠正 - 显然是在编译事物并进入链接器阶段,但是您遇到了此错误.该错误只是意味着它找不到名为initbrisk的函数,我猜这将是该模块的最高级别INIT函数.同样,这表明您正在尝试从不适合其的代码中编译一个Python模块.

如果您想将C ++代码包装在Python包装中,您可以看一下编写C的官方文档C/C ++扩展.另外,您可以看一下 boost :: Python http://www.riverbankcomputing.co.uk/software/sip/sip/intro"> sip 或 Boost Pro网站下载安装程序.这些应该安装使用Windows上的Boost C ++库所需的所有标头文件和二进制文件.请注意将这些文件安装到的位置,因为以后您需要它们 - 最好将其安装到没有空间的情况下.为了简单起见,我将假设您将这些文件放入C:\ Boost中,但您可以将其替换为实际使用的路径.

另外,您可以按照这些说明从来源建立增压.我不是100%确定的,但是您可能需要这样做,以获取与已安装的Python版本兼容的Boost :: Python版本.

设置Visual Studio项目

接下来,您需要为brisk.pyd设置一个Visual Studio项目.如果您打开Visual Studio,请转到New-> Project,请找到Win32项目的选项.设置您的位置等,然后单击"确定".在出现的向导中,选择了DLL项目类型,然后勾选为空项目复选框.

现在您已经创建了项目,您需要设置Incluble&Library路径,以允许您使用Python,Boost :: Python和Brisk.lib文件.

在Visual Studios解决方案资源管理器中,右键单击您的项目,然后从出现的菜单中选择属性.这应该打开您项目的属性页面.转到链接器 - >常规部分,并查找其他库目录部分.您需要用.lib文件的路径来填写,以进行Boost,Python和您的brisk_static.lib.通常可以在lib(或libs)的子目录中找到这些 无论您在哪里安装了库.路径被分离分离.我已经连接了下面的设置屏幕截图:

附加库目录设置

接下来,您需要让Visual Studio链接到.lib文件.这些部分可以在属性的链接器 - >输入部分的其他依赖项字段中找到.同样,这是一个半分隔列表.您应该需要添加python的库(在我的情况下,这是python27.lib,但这会因版本而异)和brisk_static.lib.当您在上一个阶段添加时,这些不需要完整的路径.同样,这是一个屏幕截图:

附加依赖关系设置

您 May 还需要添加BOOST_PYTHON库文件,但i think think boost使用一些标头文件魔术来节省您的麻烦.如果我不正确,请在您中查看您的boost库路径,以获取类似于boost_python-vc100-mt.lib的文件,然后添加.

最后,您需要设置包含路径,以允许您的项目包含相关的C ++标头文件.为了使相关设置出现在项目属性中,您需要在项目中添加.CPP文件.右键单击"解决方案资源管理器"中的源文件文件夹,然后添加新项目.选择一个C ++文件(.cpp)并将其命名为main.cpp(或其他任何您想要的).

接下来,返回您的项目属性,然后转到C/C ++ - >一般.在其他库中,您需要添加Brisk,Python和Boost的包括路径.同样,Seperator的半殖民者,这再次是屏幕截图:

在此处输入图像说明

我怀疑您可能需要更新这些设置以包含OpenCV2和Agast库,但是我将这是一项任务供您弄清楚 - 这应该是相同的过程.

用boost :: python包装现有的C ++类.

现在是一个稍有棘手的位 - 实际上编写C ++以将您的Boost Python包裹起来.您可以找到此在这里但是我也会尝试一下.

这将在您之前创建的main.cpp文件中进行.首先,添加您需要在文件顶部需要的相关语句:

#include <brisk/brisk.h>
#include <Python.h>
#include <boost/python.hpp>

接下来,您需要声明您的Python模块.我假设您希望这样称呼为快感,所以您要做这样的事情:

BOOST_PYTHON_MODULE(brisk)
{
}

这应该告诉boost :: python创建一个名为brisk的python模块.

接下来,这只是您要包装并宣布与他们一起宣布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" )使用BriskPatternPoint c10> c ++类告诉boost :: python,并将其公开为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行只是声明一个函数-BOOST :: PYTHON应该(我认为)能够自动确定函数的参数类型,因此您无需提供它们.

可能值得注意的是,我实际上还没有编译任何这些示例 - 它们可能根本不起作用.

无论如何,要在Python中完全工作,应该是为您想要从Python访问的每个结构,类,属性和功能相似的情况 - 这可能是一个很耗时的任务!

如果您想看到另一个示例,我做了这里要结束 a>

建造和使用扩展

Visual Studio应该照顾构建扩展名 - 然后,使用它只是将.dll并将其重命名为.pyd的一种情况(您可以为您提供VS,但我将其保留为你).

然后,您只需要将Python文件复制到Python路径上的某个地方(例如site-packages),导入并使用它!

import brisk

patternPoint = brisk.BriskPatternPoint()
....    

无论如何,我已经花了一个小时左右的时间来写这本书 - 所以我要在这里停下来.抱歉,如果我遗漏了任何东西,或者如果没有任何内容不清楚,但是我主要是通过记忆来做到这一点.希望这对您有所帮助.如果您需要任何澄清的内容,请发表评论,或提出另一个问题.

其他推荐答案

如果有人需要它,那我到目前为止拥有的.基本上可以在python中创建的 briskfeaturedetector ,然后将检测到.其中大部分只是确认/复制Obmarg向我展示的内容,但我添加了一路到达PYD库的详细信息.

检测方法对我来说仍然不完整,因为它不会转换数据类型.任何知道改进这一点的好方法的人,请这样做!我确实找到了,例如,似乎转换的图书馆 cv ::垫子的numpy ndarray,但我没有时间弄清楚如何整合它.还有其他需要转换的数据类型.

安装 opencv 2.2 /p>

  • 对于下面的设置,我安装到C:\opencv2.2
  • 关于API或实施的某些内容已通过2.4版改变了我的问题(也许是新算法对象?),所以我坚持使用2.2,开发了哪个Brisk.

安装 boost 带有boost python

  • 对于下面的设置,我安装到C:\boost\boost_1_47

创建一个Visual Studio 10项目:

  • 新项目 - > win32
  • 对于下面的设置,我将其命名brisk
  • 下一个 - > DLL应用程序类型;空项目 - >完成
  • 在顶部,从 debug win32更改为版本 win32

在源文件中创建main.cpp

在项目设置之前执行此操作,以便在项目设置中使用C ++选项

#include <boost/python.hpp>
#include <opencv2/opencv.hpp>
#include <brisk/brisk.h>

BOOST_PYTHON_MODULE(brisk)
{
    using namespace boost::python;

    //this long mess is the only way I could get the overloaded signatures to be accepted
    void (cv::BriskFeatureDetector::*detect_1)(const cv::Mat&,
                std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint>>&,
                const cv::Mat&) const
                = &cv::BriskFeatureDetector::detect;
    void (cv::BriskFeatureDetector::*detect_vector)(const std::vector<cv::Mat, std::allocator<cv::Mat>>&,
                std::vector< std::vector< cv::KeyPoint, std::allocator<cv::KeyPoint>>, std::allocator< std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint>>>>&,
                const std::vector<cv::Mat, std::allocator<cv::Mat>>&) const
                = &cv::BriskFeatureDetector::detect;

    class_< cv::BriskFeatureDetector >( "BriskFeatureDetector", init<int, int>())
        .def( "detect", detect_1)
    ;
}

项目设置(右键单击项目 - >属性):

  1. 包括/标头

    • 配置属性 - > c/c ++ - >常规
    • 添加到附加包括目录(调整到您自己的python/brisk/等.基本路径):

      C:\opencv2.2\include;

      C:\boost\boost_1_47;

      C:\brisk\include;C:\brisk\thirdparty\agast\include;

      C:\python27\include;

  2. 库(链接器)

    • 配置属性 - >链接器 - >常规
    • 添加到附加库目录(调整到您自己的python/brisk/等.基本路径):

      C:\opencv2.2\lib;

      C:\boost\boost_1_47\lib;

      C:\brisk\win32\lib;

      C:\python27\Libs;

    • 配置属性 - >链接器 - >输入

    • 添加到其他依赖项(调整到您自己的Python/Brisk/等.基本路径):

      opencv_imgproc220.lib;opencv_core220.lib;opencv_features2d220.lib;

      agast_static.lib; brisk_static.lib;

      python27.lib;

  3. .pyd输出而不是.dll

    • 配置属性 - >常规
    • 将目标扩展更改为.pyd

必要时构建并重命名

  • 右键单击解决方案并构建/重建
  • 您可能需要将输出从" brisk.pyd"重命名为" brisk.pyd",否则python会给您无法加载DLL
  • 的错误
  • 通过将其放入站点包中或放置一个.pth文件链接到其路径

更新路径环境变量

  • 在Windows设置中,确保以下路径中包含以下内容(再次调整到路径):

    `C:\boost\boost_1_47\lib;C:\brisk\win32\bin`
    

本文地址:https://www.itbaoku.cn/post/359208.html