gpt4 book ai didi

c++ - 如何从c/c++源代码获取Windows的python .pyd? (更新: brisk now in Python in case that's what you want)

转载 作者:行者123 更新时间:2023-12-01 19:38:39 25 4
gpt4 key购买 nike

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

编辑:我想要使用的特定库(BRISK)包含在OpenCV 2.4.3中,因此我暂时对这种技能的需求消失了。如果您是来这里寻找危险的,这是我发布的一个简单的BRISK in Python demo

我有想要在python应用程序中构建和使用的Brisk源代码(download)。我可以生成一个brisk.pyd文件...但是它是0字节。如果有一种针对brisk.pyd文件的更好/替代的方法,那么我当然也愿意这样做。

编辑:请忽略下面我原始问题中的所有尝试,并查看我的答案是由obmarg的详细演练提供的

我要去哪里错了?

  • 没有库路径的Distutils:首先,我尝试使用distutils和以下setup.py来构建源代码(我刚刚开始学习distutils,所以这是一个黑暗的镜头)。 BRISK源代码的结构位于该问题的底部,以供引用。
    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
  • 带有库路径的Distutils:尝试尝试。因此,我添加了在上面的setup.py中注释掉的两个库行。在出现此链接错误之前,这似乎没问题:
    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
  • 无法控制的摆动:我认为可能需要构建库,因此我使用cmake + mingw-mingw + vc++ express 2010进行了速成类(class)(很多速成类(class)),如下所示:
  • cmake gui:来源:c:/brisk,构建:c:/brisk/build
  • cmake gui:为Visual Studio 10配置
  • cmake gui:使用默认选项并生成(CMAKE_BACKWARDS_COMPATIBILITY,CMAKE_INSTALL_PREFIX,EXECUTABLE_OUTPUT_PATH,LIBRARY_OUTPUT_PATH)
  • VC++ Express 10:更改为Release,并构建由cmake生成的解决方案,并获得大约20页的非关键警告,随后所有警告均成功通过。注意-不会生成任何dll。它的确会生成以下库,其大小与下载所包含的库大小相似:
    win32/lib/Release/
    agast_static.lib
    brisk_static.lib
  • 进一步出错。

  • 相关的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绑定(bind)吗?我在源代码中看不到任何引用-它甚至似乎都没有导入python头文件。这肯定可以解释为什么到目前为止您没有取得太大的成功-您不能只编译纯C++代码并期望python与之交互。

    我认为您的第二个distutils示例最接近正确-它显然是在编译内容并进入链接器阶段,但是随后遇到此错误。该错误只是意味着它找不到名为initbrisk的函数,我猜这将是模块的顶级init函数。同样,这表明您正在尝试从不适合它的代码中编译python模块。

    如果您想自己将C++代码包装在python包装器中,则可以看看the official documentation on writing c/c++ extensions。另外,您可以看看boost::pythonSIPshiboken,它们尝试某种程度(或完全)自动化从C++代码制作python扩展的过程。

    编辑:既然您似乎已经为自己解决问题做出了相当大的努力,并发布了一个很好的问题,我决定就如何执行此操作给出更详细的答复。

    使用boost::python包装C++库的快速教程

    就我个人而言,我只使用过boost::python这样的东西,所以我将尝试为您做一个很好的总结。我将假定您使用的是Visual C++2010。我还将假定您安装了32位版本的python,因为我相信boost pro库仅提供32位二进制文​​件。

    安装升压

    首先,您需要获取boost库的副本。最简单的方法是从the boost pro website下载安装程序。这些应该安装在Windows上使用boost c++库所需的所有头文件和二进制文件。请注意将这些文件安装到的位置,因为稍后将需要它们-最好将其安装到路径中没有空格的位置。为简单起见,我假设您将这些文件放在C:\boost中,但是您可以将其替换为实际使用的路径。

    另外,您可以按照these instructions从源代码构建增强功能。我不确定100%,但是可能是为了获得与您安装的python版本兼容的boost::python版本,您需要这样做。

    设置视觉工作室项目

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

    现在,您已经创建了项目,您需要设置include&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。这些不需要完整路径,就像您在上一阶段中添加的那样。同样,这是一个屏幕截图:

    您可能还需要添加boost_python库文件,但是我认为boost使用一些头文件魔术可以为您节省麻烦。如果我不正确,那么请查看一下提升类似于boost_python-vc100-mt.lib的文件的库路径并将其添加。

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

    接下来,返回您的项目属性,然后转到C/C++-> General。在附加库目录下,您需要添加轻快,python和boost的包含路径。再次,为分隔符使用分号,并再次提供屏幕截图:

    我怀疑您可能需要更新这些设置以同时包含opencv2和agast库,但我将把它留给您自己解决,因为它应该是相同的过程。

    用boost::python包装现有的c++类。

    现在有点棘手了-实际编写C++将您的轻快库包装在boost python中。您可以找到有关here的教程,但我也将尝试对其进行详细介绍。

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

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

    接下来,您需要声明您的python模块。我假设您希望将此功能称为“轻快”,因此您可以执行以下操作:
    BOOST_PYTHON_MODULE(brisk)
    {
    }

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

    接下来,只是遍历您要包装的所有类和结构并用它们声明boost python类的情况。所有的类的摘要都应包含在brisk.h中。您只应包装类(class)的公共(public)成员,而不应包装任何 protected 成员或私有(private)成员。举个简单的例子,我在这里做了几个结构:
    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++类声明一个类,并在python中将其公开为 BriskPatternPoint
    .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访问的每个结构,类,属性和函数执行类似的操作-这可能是一项非常耗时的工作!

    如果您想查看此操作的另一个示例,我做了 this here来包装 this class

    构建和使用扩展

    Visual Studio应注意构建扩展名-然后使用它只是将.DLL并将其重命名为.pyd的一种情况(您可以让VS为您完成此操作,但我将由您自己决定)。

    然后,您只需要将python文件复制到python路径上的某个位置(例如 site-packages),将其导入并使用即可!
    import brisk

    patternPoint = brisk.BriskPatternPoint()
    ....

    无论如何,我已经花了一个小时左右的时间写出来了,所以我将在这里停止。抱歉,如果我遗漏了任何内容或不清楚的内容,但是我主要是从内存中执行此操作。希望它对您有所帮助。如果您需要任何澄清,请发表评论或提出其他问题。

    关于c++ - 如何从c/c++源代码获取Windows的python .pyd? (更新: brisk now in Python in case that's what you want),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10664658/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com