使用 Cython 和 C++ 进行项目组织

2023-11-21

我想为我的 C++ 项目提供 Python 接口。从技术上讲,我决定使用 Cython 来包装 C++ 代码。随着时间的推移,整个项目将成为一个 Python 扩展模块,但起初,这是高度实验性的。逐渐地,C++ 类需要暴露给 Python。

我的问题是如何最好地组织文件和构建配置,以便 Cython 生成的和人工编写的 C++ 代码不会混合,并且 Python 扩展模块与其他目标分开构建。

我想象了这样的源文件目录结构,以及 Cython 的一些构建目录。

Project/
    src/
        *.h
        *.cpp
    cython/
        Project.pyx
        setup.py

基本上我有3个文件夹:

  1. CPROJECT, C++ 库:生成一个libcproject.so共享对象
  2. CYPROJECT, cythonized Python 扩展:生成cyproject.so使用 Cython
  3. DEPENDENCIES,依赖项:我在其中复制两个项目的外部需求

In 1.我构建了 C++ 扩展(用 gcc 编译 --shared, -fPIC编译选项)将暴露给 python 并且CYPROJECT依赖于向 Python 公开功能。作为后处理命令,结果.so被复制到DEPENDENCIES/libcproject/(以及include文件)。这样,该库当然也可以在纯 C++ 项目中独立使用。

In 2.我使用 3 个子文件夹:

  • adapters:主要包含 C++ 附加类(通常是从 C++ 提供的类派生的类)libcproject.so)。这些通常是通过特定于 Cython 需求的功能来增强的类(例如存储PyObject *目标 Python 版本的 C 版本 - 继承自object- 给定类和引用计数管理,通过Py_XINCREF and Py_DECREF, ...).
  • pyext:所有 Cython 手写都存储在哪里.pyx files.
  • setup: 包含setup.sh脚本(用于设置依赖路径并调用python setup.py build_ext --inplace用于生成最终的cyproject.so(要添加到PYTHONPATH) and cyproject.pyx.

那么里面有什么setup子文件夹?

这是一个示例代码setup.sh :

export PYTHONPATH=$PYTHONPATH:../../../DEPENDENCIES/Cython-0.18
export PATH=$PATH:../../../DEPENDENCIES/libcproject:../../../DEPENDENCIES/Cython-0.18/bin

# Note the `../../../DEPENDENCIES/libcproject`...

CC="gcc"   \
CXX="g++"   \
    python setup.py build_ext --inplace

这里有一个例子setup.py(主要是为了演示如何附加adapters已编译):

import sys
import os
import shutil

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

# Cleaning
for root, dirs, files in os.walk(".", topdown=False):
    for name in files:
        if (name.startswith("cyproject") and not(name.endswith(".pyx"))):
            os.remove(os.path.join(root, name))
    for name in dirs:
        if (name == "build"):
            shutil.rmtree(name)

# Building
setup(
    cmdclass = {'build_ext': build_ext},
    ext_modules = [
    Extension("cyproject", 
              sources=["cyproject.pyx", \
                       "adapter/ALabSimulatorBase.cpp", \
                       "adapter/ALabSimulatorTime.cpp", \
                       "adapter/ALabNetBinding.cpp", \
                       "adapter/AValueArg.cpp", \
                       "adapter/ALabSiteSetsManager.cpp", \
                       "adapter/ALabSite.cpp", \
                       ],
              libraries=["cproject"],
              language="c++",
              extra_compile_args=["-I../inc", "-I../../../DEPENDENCIES/python2.7/inc", "-I../../../DEPENDENCIES/gsl-1.8/include"], 
              extra_link_args=["-L../lib"]
              extra_compile_args=["-fopenmp", "-O3"],
              extra_link_args=[]
              )
    ]
)                   

最后,主要的.pyx,链接所有手写的.pyxcython 部分的 s 一起 [cyproject.pyx] :

include "pyext/Utils.pyx" 
include "pyext/TCLAP.pyx" 
include "pyext/LabSimulatorBase.pyx"
include "pyext/LabBinding.pyx"
include "pyext/LabSimulatorTime.pyx"
...

注意:Cython 生成的所有文件都保留在此setup文件夹,与手写的东西分开(adapters and pyext),正如预期的那样。

In 3.使用分离的DEPENDENCIES文件夹允许将事物分开(以防我将移动CYPROJECT- 及其依赖项 - 在其他一些环境中)。

所有这些都是为了让您对如何组织此类项目有一个概述(我希望是一个相关的概述)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Cython 和 C++ 进行项目组织 的相关文章

随机推荐

  • 如何根据 Git 分支的名称为其着色?

    我的本地 git 存储库中有许多分支 并且我保留了特定的命名约定 这有助于我区分最近使用的分支和旧分支 或者区分与 master 合并的分支和未合并的分支 有没有办法在输出中为分支名称着色git branch根据一些基于正则表达式的规则而不
  • 如何调试 .BAT 脚本?

    有没有办法单步执行 bat 脚本 问题是 我有一个构建脚本 它调用很多其他脚本 我想看看它们的调用顺序是什么 这样我就可以知道我到底应该去哪里并添加我的修改 我不知道如何逐步执行 bat 文件 但您可以使用echo and pause帮助调
  • 定义在 Swift 中被视为类的结构

    在斯威夫特String结构也被视为类对象 就像使用NSCoder encodeObject forKey 方法 我确实知道String直接与 Objective C 类桥接 NSString 但是有没有办法定制struct其行为类似 也许将
  • REST 应用程序的 RequestBody

    我对 SpringMVC REST 概念有点陌生 需要专家的帮助来理解 解决以下问题 我开发了一个 SpringMVC 应用程序 以下是控制器类代码的一部分 它按原样工作得很好 这意味着它可以与 JSON 类型对象一起工作 RequestM
  • docker-compose 上的 WordPress 无法运行

    这是我的 docker compose yml version 2 services wordpress image wordpress ports 8080 80 environment WORDPRESS DB PASSWORD exa
  • Python Scrapy - 从 mysql 填充 start_urls

    我正在尝试使用 MYSQL 表中的 SELECT 来填充 start url蜘蛛 py 当我运行 scrapy runningpider Spider py 时 我没有得到任何输出 只是它完成时没有错误 我已经在 python 脚本中测试了
  • 使用 CoreData 在 iPhone 上导入大型数据集

    我面临着非常烦人的问题 我的 iPhone 应用程序正在从网络服务器加载数据 数据以 plist 形式发送 解析时需要使用 Core Data 将其存储到 SQLite 数据库 问题是 在某些情况下 这些数据集太大 5000 多条记录 导入
  • java.net.UnknownHostException:无法解析主机“”:没有与主机名关联的地址,且输入结束位于字符 0 处

    我创建了一个从我的网络服务加载问题的应用程序 并且运行良好 但是 有时它会崩溃 我不明白为什么会发生这种情况 特别是因为我也给了它所需的权限 它工作正常 但随机崩溃并给我这个报告 private void sendContinentQues
  • 多个 goroutine 监听一个通道

    我有多个 goroutine 尝试同时在同一通道上接收数据 看起来最后一个在通道上开始接收的 Goroutine 获得了该值 这是语言规范中的某个地方还是未定义的行为 c make chan string for i 0 i lt 5 i
  • android 中奇怪的 webview goBack 问题

    我在 Android 中使用 webview 但奇怪的是 有时甚至是webviewcanGoBack方法返回true 网页视图goBack方法不起作用 if webView canGoBack webView goBack 谢谢你的任何想法
  • Oracle 写入文件

    我正在运行 Oracle 并有一个查询从数据库中提取一些结果 我想将结果写入文本文件 我该怎么做呢 我首选的方法是使用 UTL FILE 有人可以举例说明如何做到这一点吗 如果您使用 Sql Plus 则非常简单 SQL gt spool
  • iOS 中如何获取触摸尺寸?

    我明白那个这个回应明确指出 如果没有私有函数调用 这是不可能的 因此 根据苹果的条款 这种方式不能在App Store应用程序上使用 然而 一些应用程序似乎已经使用了这个函数调用 倒数第二个用于实际防手掌误触 无需像 Note Taker
  • GL 表面和能见度:消失

    因此 我的应用程序中有一个 GLSurfaceView 由 GLSurfaceView Renderer 渲染并使用 JPCt 作为库 表面位于不可见的RelativeLayout 中 可见性 消失 当我将可见性更改为 可见 然后返回 消失
  • 防止 JavaScript 函数运行两次 (setTimeout)

    我有一个运行几秒钟的函数 使用setTimeout 单击按钮时将运行此函数 function complete var div document getElementById log setTimeout function div inne
  • 取消引用空指针

    为什么我无法取消引用空指针 也就是说 为什么我无法读 写地址为 0 的内存 我的进程的基指针是否有不同的地址 如果是 有没有办法获得可用于我的进程的默认堆的较低内存加法器 空指针不是指向 地址仅为 0 的内存 的指针 它只是一个特殊的指针
  • kubernetes pod 无法(通过服务)连接到自身,只能连接到其他 pod 容器

    我有一个 kubernetes 单节点设置 请参阅https coreos com kubernetes docs latest kubernetes on vagrant single html 我有一个服务和一个创建 Pod 的复制控制
  • WPF/MVVM:当 UserControl 后面的 ViewModel 尚未初始化时禁用按钮的状态?

    我有一个带有 ListBox 和 3 个按钮的 DocumentListView Xaml 在该 UserControl 后面是一个 DocumentListViewModel 其中包含 3 个按钮 并且它们的 Command 属性绑定到
  • 默认表单 HTTP 方法是什么?

    当提交 HTML 表单而不指定方法时 默认使用的 HTTP 方法是什么 获取还是发布 HTML 标准之间的这种行为是否发生过变化 如果可能 请引用 W3C 标准文档 这是获取 看一看W3C 取代建议 17 3 FORM 元素 Excerpt
  • 判断一个整数是否在另外两个整数之间

    如何确定给定整数是否在两个其他整数之间 例如大于 等于10000且小于 等于30000 if 10000 lt number lt 30000 pass 有关详细信息 请参阅docs
  • 使用 Cython 和 C++ 进行项目组织

    我想为我的 C 项目提供 Python 接口 从技术上讲 我决定使用 Cython 来包装 C 代码 随着时间的推移 整个项目将成为一个 Python 扩展模块 但起初 这是高度实验性的 逐渐地 C 类需要暴露给 Python 我的问题是如