V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
seth19960929
V2EX  ›  Python

Python 调用 C++ 参数包含 vector<double> 类型是不是不行?

  •  
  •   seth19960929 ·
    seth-shi · 4 天前 · 1083 次点击
    查了文档, 没看到有对应类型

    GPT 给的建议是使用

    ```
    weights = (c_double * 5)(0.3, 0.2, 0.2, 0.15, 0.15)
    ```

    使用 GPT 建议直接返回 Segmentation fault (core dumped) 错误了,
    有大神熟悉这方便吗?

    ****
    还有一个问题, 我看 Segmentation fault (core dumped) 会导致程序直接退出, 如果我是一个 web 接口代理调用 so, 崩溃会导致整个程序停止? 有什么好的处理方式吗
    24 条回复    2025-03-28 14:57:25 +08:00
    sujin190
        1
    sujin190  
       4 天前   ❤️ 1
    ctypes ? ctypes 似乎没有 vector 的类型映射吧,python 层面想构建出 vector 要求一致内存结构是不是做不到吧,内存结构不对自然 Segmentation fault (core dumped)了

    https://stackoverflow.com/questions/49744870/passing-vector-from-a-c-dll-in-python-ctypes
    Monad
        2
    Monad  
       4 天前 via iPhone   ❤️ 2
    如果想具体 hack 某个版本实现的 vector 没啥问题(毕竟怎么看都是 size+capacity+首地址指针)不过你真的要做这么不兼容的东西吗..
    和其他语言交互一律改用 c 接口
    seth19960929
        3
    seth19960929  
    OP
       4 天前
    @sujin190 对, ctypes, 一般用什么结构
    @Monad 懂了, 直接用 *double 吗?
    sujin190
        4
    sujin190  
       4 天前   ❤️ 1
    @seth19960929 #3 ctypes 只能用 c 标准的数据结构吧,是不是应该用指针,函数也需要声明为 c 导出

    weights = (c_double * 5)(0.3, 0.2, 0.2, 0.15, 0.15)这个就是指针吧,Segmentation fault (core dumped)了就是和 vector 要求的内存布局和对其不匹配
    qieqie
        5
    qieqie  
       4 天前 via iPhone   ❤️ 1
    ctypes 只能用 c api ,你需要在接口上把 vector<double>换成 double*和 size_t
    Huelse
        6
    Huelse  
       4 天前   ❤️ 1
    推荐 pybind11 ,有对应的接口和抽象,基本兼容 c++
    mightybruce
        7
    mightybruce  
       4 天前   ❤️ 1
    python 无法直接使用 c++ 的数据类型,需要转换为 C 的函数 和结构体, 借助 pybind11, boost.Python 可以实现。
    ysc3839
        8
    ysc3839  
       4 天前 via Android   ❤️ 1
    不行,或者说极其麻烦,只能写 C++代码对接
    ysc3839
        9
    ysc3839  
       4 天前 via Android
    崩溃问题的话单独用一个进程运行吧,暴露网络接口出来调用。
    ysc3839
        10
    ysc3839  
       4 天前 via Android
    其实看你这种需求,大概适合单独用 C++搭配 cpp-httplib 之类的超级简单的库实现一个 HTTP Server ,通过 HTTP API 把 so 的接口暴露给 Python 使用。崩溃了也能快速重启,不影响主要业务。
    leonshaw
        11
    leonshaw  
       4 天前 via Android   ❤️ 1
    跨语言一律用 C ,C++ 自己 ABI 都没整统一。
    jim9606
        12
    jim9606  
       4 天前 via Android   ❤️ 1
    几乎所有跨语言 interprop 都只能用 c 风格 api,你得写个 wrapper 把 c++的结构转封装成 c 风格的再传递到 cpython
    seth19960929
        13
    seth19960929  
    OP
       4 天前
    @Huelse ctypes 用起来简单
    @mightybruce 感谢
    @ysc3839 #9 那我选择用容器来运行把, 不然另起一个太麻烦了
    @leonshaw OK
    jones2000
        14
    jones2000  
       3 天前   ❤️ 1
    直接把 vector 序列化字符串,给 c++,c++再反序列化生成一个 vector.
    seth19960929
        15
    seth19960929  
    OP
       3 天前
    @jim9606 好的
    @jones2000 会影响效率吧
    jones2000
        16
    jones2000  
       3 天前
    @seth19960929 “影响效率”, 具体看你的业务, 如果 c++调用传参数据量很小, 字符串序列化基本不会影响什么效率,
    如果传参量大
    1. 直接用共享内存, 把 py 数据直接转结构化写入共享内存或共享文件,c++直接读结构化的共享内存数据( memcpy).
    2. 通过管道传数据(本机),也可以用 tcp 长连接传数据(可以支持集群模式)
    .......
    都用 c++写了, 没有什么解决不了的问题。
    seth19960929
        17
    seth19960929  
    OP
       2 天前
    @jones2000 #16 现在 C++ 的同事换成 const float* 运行 print 代码了, 但是后续还是会出现 Segmentation fault (core dumped) ,是因为他们代码的原因?
    seth19960929
        18
    seth19960929  
    OP
       2 天前
    请问一下, pybind11 生成的 so 和 demo.py 直接运行没问题, 但是放到其它文档导入
    seth19960929
        19
    seth19960929  
    OP
       2 天前
    请问一下, pybind11 生成的 so 和 demo.py 直接运行没问题, 有两个问题请大神答复一下
    1. 其它文件引入(比如在 fastapi 路由 import 马上报错 ModuleNotFoundError: No module named 'xxx'), 我去 import demo.py 也不行
    2. 在 A 机器使用 pybind11 构建出来, 在 B 机器最少需要保留的文件是什么呢


    @Huelse
    @mightybruce
    @sujin190
    @Monad
    @qieqie
    @jones2000
    qieqie
        20
    qieqie  
       2 天前 via iPhone
    @seth19960929 vector 还需要一个把 size()传到 c 接口,要不可能访问越界。另外就是注意 vector 本身的作用域,很可能把指针传给你的 python 之后 vector 就析构了。
    ModuleNotFound 一般是没有__init__.py 或者用了相对 import 之类的问题。
    seth19960929
        21
    seth19960929  
    OP
       2 天前
    @qieqie #20 目前看不是相对 import, 我试了一下, C++ 同时给的文件很多, 我把两个文件放到一个新的目录
    ```
    app
    libs
    demo.py
    demo_add.cpython-311-x86_64-linux-gnu.so
    routes
    api.py
    ```

    我在命令行上运行 python app/libs/demo.py 是 OK 的
    但是我在 api.php 文件 from app.libs.demo import add 会提示有问题
    seth19960929
        22
    seth19960929  
    OP
       2 天前
    回复的代码格式不好, 贴了个图
    qieqie
        23
    qieqie  
       2 天前 via iPhone
    @seth19960929 看看 sys.path
    seth19960929
        24
    seth19960929  
    OP
       2 天前
    @qieqie #23 懂了, 我改一下环境变量
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5409 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 01:35 · PVG 09:35 · LAX 18:35 · JFK 21:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.