V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wisefree
V2EX  ›  C

请教 C++ Python 进程间通信

  •  
  •   wisefree · 2019-05-14 21:23:03 +08:00 · 8647 次点击
    这是一个创建于 2018 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请教各位 V 友一个问题,我正在使用海康威视摄像头,官方给了很全的代码范例,包括 C++、Java、C# 但是没有给出 Python 的,如果用 Python 中的 ctypes 库来调用官方的 DLL,写起来十分的复杂

    目前的粗略想法

    1. 用 C++来获取实时的图片
    2. 将获取的图片,交给 Python 来处理

    请问大家有合适的方案么?

    注:

    • 不只一个摄像头,可能有 4 个以上
    • 为什么不全程用 C++,因为要用到 Python 中的一些库
    • 不用 rstp 协议,因为它延时太高
    第 1 条附言  ·  2019-05-15 22:19:33 +08:00

    谢谢各位V友的方案,有用的回复均已经感谢,抱拳。

    我来总结下吧,便于后来的读者

    • 用 C++封装一个 C ABI 兼容的接口库

    • 编写一个python的extension

    • cython、swig、pybind11、cffi、boost.python

    • 网络通信

      • gRPC
      • zeromq
      • thrift
      • webrtc

    大大扩大的眼界,很多知识以前都没有听说过,:)

    70 条回复    2019-05-16 19:01:38 +08:00
    CSM
        1
    CSM  
       2019-05-14 21:28:04 +08:00 via Android   ❤️ 1
    Python 起一个 HTTP 服务器,C++每得到一个图片就 post 过去?(我猜的)
    bsidb
        2
    bsidb  
       2019-05-14 21:33:42 +08:00   ❤️ 2
    gRPC
    Leigg
        3
    Leigg  
       2019-05-14 21:35:17 +08:00 via iPhone   ❤️ 1
    你是想在内存中直接将图片流传给 python 吧
    C++是可以调用 python 函数的,你找一下相关资料吧
    这里有一个不是很详细但肯定需要折腾会儿
    https://mp.weixin.qq.com/s/VFYrFB63BKd-W3yaJqE2NQ
    不如 1 楼那样开发快。
    hakono
        4
    hakono  
       2019-05-14 21:42:18 +08:00 via iPhone   ❤️ 1
    相信我别尝试 python 调 dll 或者 c 调用 python
    到时候这种跨语言调用,调试起来告诉你什么叫地狱。。。。

    乖乖用通用的网络协议传就好了。c 艹建个服务器 python 获取,或者 1 楼那样 python 建个服务器 c 往里传数据

    如果是楼上说的直接往内存里写数据,其实也能做到。Windows 的话看一下进程之间的 共享内存 怎么搞就知道了
    catror
        5
    catror  
       2019-05-14 21:45:52 +08:00 via Android   ❤️ 1
    webrtc 吧,C++进程跑服务端,Python 进程跑客户端。定义好交互协议,客户端可以控制服务端,同时服务端有数据可以实时推送给客户端处理。
    goreliu
        6
    goreliu  
       2019-05-14 21:46:04 +08:00 via iPhone   ❤️ 1
    摄像头是通用设备,用 Python 应该可以直接处理,找找相关的库,不用局限于官方。
    nooper
        7
    nooper  
       2019-05-14 21:58:41 +08:00
    外包给我,cython 搞定,可以结合 opencv 等
    justou
        8
    justou  
       2019-05-14 22:04:20 +08:00   ❤️ 1
    用过大华相机的 sdk 跟 Sapera LT sdk, 如果机制都差不多的话, 都是通过一个回调函数获取图像, 这样的话不如在 cython 中直接使用其 sdk 的函数, 然后传给 python 处理就很容易了.
    wisefree
        9
    wisefree  
    OP
       2019-05-14 22:09:22 +08:00
    @CSM 不管是不是猜的,先感谢一波
    GeruzoniAnsasu
        10
    GeruzoniAnsasu  
       2019-05-14 22:09:40 +08:00 via Android   ❤️ 1
    用 c++实现一个 python module 要比在 python 里用 ctypes 跨语言调用好得多

    把要用的接口封装一下给 python 层就 ok 了
    wisefree
        11
    wisefree  
    OP
       2019-05-14 22:09:43 +08:00
    @bsidb 谢啦,我去看看这方面的资料
    wisefree
        12
    wisefree  
    OP
       2019-05-14 22:11:13 +08:00
    @hakono 感谢!:),不想下地狱,我会好好看看通用网络协议这个方案的
    qieqie
        13
    qieqie  
       2019-05-14 22:11:37 +08:00   ❤️ 1
    方法 1:用 C++封装一个 C ABI 兼容的接口库,然后用 CDLL 调用
    方法 2:写一个 CPython 的 extension,这方面登峰造极的是 OpenCV,它的 wrapper c++代码甚至是用 python 代码生成出来的
    wisefree
        14
    wisefree  
    OP
       2019-05-14 22:12:01 +08:00
    @goreliu 海康好像不行,调用 sdk,获得的图像才是实时的
    wisefree
        15
    wisefree  
    OP
       2019-05-14 22:13:09 +08:00
    @catror 学到了,我去看看哈,好像都是推荐用网络协议,感谢!
    wisefree
        16
    wisefree  
    OP
       2019-05-14 22:16:09 +08:00
    @GeruzoniAnsasu @qieqie 我也考虑过封装,但是有一个问题,C++返回的数据并不是整数、字符串等类型,而是 Opencv 中的 Mat 对象,这个返回类型,用 Python 如何将接收呢?
    wisefree
        17
    wisefree  
    OP
       2019-05-14 22:20:40 +08:00
    @justou 还没有了解过 cython,涨知识了,我去 google 下基本用法,感谢!
    qieqie
        18
    qieqie  
       2019-05-14 22:21:24 +08:00   ❤️ 1
    @wisefree 只返回基本类型,拿 OpenCV 来说,你把图片 encode 成某种格式,比如 jpeg png 然后传 byte 数组就行了
    husterqq
        19
    husterqq  
       2019-05-14 22:40:56 +08:00   ❤️ 1
    pybind
    wisefree
        20
    wisefree  
    OP
       2019-05-14 22:58:11 +08:00
    @qieqie 大致明白了,谢谢给出的思路
    wisefree
        21
    wisefree  
    OP
       2019-05-14 22:58:46 +08:00
    @husterqq 这个问题,真让我长见识了,好多库我都不知道,谢啦
    xiaoyaocmx
        22
    xiaoyaocmx  
       2019-05-14 23:09:36 +08:00   ❤️ 2
    我也遇到过这个问题,考虑过 pybind11,然后用了 zeromq
    wisefree
        23
    wisefree  
    OP
       2019-05-14 23:15:31 +08:00
    @xiaoyaocmx 这今天也搜到了 zeromq 这个解决方案,你用了 protobuf 了么?
    goreliu
        24
    goreliu  
       2019-05-14 23:17:27 +08:00 via iPhone   ❤️ 1
    @wisefree 搜了下,有很多调 dll 的文章,比如这个:
    https://www.ryannn.com/archives/hikvision
    看起来不是很麻烦,不如试试,不行的话再进程通信。
    dfjslkjdf
        25
    dfjslkjdf  
       2019-05-14 23:28:02 +08:00   ❤️ 1
    sepelf
        26
    sepelf  
       2019-05-15 07:00:22 +08:00 via iPhone   ❤️ 1
    thrift 了解下
    wisefree
        27
    wisefree  
    OP
       2019-05-15 07:41:52 +08:00
    @goreliu 简单的用 ctypes 封装,写起来很方便,复杂的回调函数、结构体指针什么的,用 ctypes 容易了。swig,这个方案倒是可以考虑下
    wisefree
        28
    wisefree  
    OP
       2019-05-15 07:47:05 +08:00
    @sepelf 感谢 :),昨天搜索 gRPC,搜到了这个
    wisefree
        29
    wisefree  
    OP
       2019-05-15 07:53:39 +08:00
    @wisefree 27 楼,应该是:**用 ctypes 不容易了。**
    binux
        30
    binux  
       2019-05-15 08:50:21 +08:00   ❤️ 1
    根据我古老的记忆,ctypes 调不了 C++ 吧,你的封装一次吧
    thfurior
        31
    thfurior  
       2019-05-15 09:05:59 +08:00   ❤️ 1
    ls+1,ctypes 调不了 c++,只能调 c 封装成的 dll/so,我以前搞过用 boost python 封装 c++的 python 库,使用非常方便,楼主不妨试试
    Moker
        32
    Moker  
       2019-05-15 09:35:26 +08:00   ❤️ 1
    进程通信上共享内存吧 或者把 go 当成粘合剂试下?
    sujin190
        33
    sujin190  
       2019-05-15 09:51:31 +08:00   ❤️ 1
    cython 之前用过,似乎无法完全自动解析 struct 或是 class 提供的指针,不过标准类型比如 char 的支持还是不错的,建议可以写一个 c 文件返回 char 字节流,然后在 python 中导入调用这个函数接收字节流,再用 cython 把 python 文件编译成扩展就行了,性能也不错的,不过我觉得写一个 python 扩展也不难啊
    geelaw
        34
    geelaw  
       2019-05-15 09:59:58 +08:00 via iPhone   ❤️ 1
    也并不非要用网络协议,命名管道就可以。
    Yoock
        35
    Yoock  
       2019-05-15 10:03:43 +08:00 via iPhone   ❤️ 1
    IPC
    dinjufen
        36
    dinjufen  
       2019-05-15 10:07:06 +08:00   ❤️ 2
    卧槽,这个我刚做过。我用的 boost/python 库,参见:http://www.pianshen.com/article/5251280159/,在 C++部分将海康摄像头图片转为 Python 直接可用的 PyObject,Python 那边用 opencv-python 直接可用,很方便,就是配置麻烦。不过你说的实时是要延迟多低?我做的延迟 70ms 左右
    dinjufen
        37
    dinjufen  
       2019-05-15 10:07:54 +08:00   ❤️ 1
    @dinjufen 链接多了一个逗号和汉字
    ipwx
        38
    ipwx  
       2019-05-15 10:36:22 +08:00   ❤️ 1
    图片用 mmap 或者别的 shared memory 手段直接共享内存,然后依靠 socket/named mutex & inter-process queue 之类的进行协调,这个方案怎么样?
    Arnie97
        39
    Arnie97  
       2019-05-15 10:45:01 +08:00 via Android   ❤️ 1
    网络协议当然可以,除此之外可以看看这几种比选方案
    https://github.com/tleonhardt/Python_Interface_Cpp
    zhongchengyong
        40
    zhongchengyong  
       2019-05-15 10:57:08 +08:00   ❤️ 1
    提供一些新思路:之前使用 Python 调用 C/C++用的是 swig,也看到有使用 CFFI 的。
    BingoXuan
        41
    BingoXuan  
       2019-05-15 11:03:49 +08:00 via Android   ❤️ 1
    我一般选择 zmq,默认可以传输 json 数据,写一个 jsonrpc 也是很快
    wisefree
        42
    wisefree  
    OP
       2019-05-15 11:55:54 +08:00
    @binux 古老且正确,ctypes 调用不了,需要再封装下,:)
    @thfurior 嗯嗯,好的,:)
    wisefree
        43
    wisefree  
    OP
       2019-05-15 11:57:02 +08:00
    @sujin190 谢谢提供思路,实在不想写 python 扩展,这是一片太新的天地了:)
    wisefree
        44
    wisefree  
    OP
       2019-05-15 11:57:56 +08:00
    @geelaw 谢谢提供思路,:)
    wisefree
        45
    wisefree  
    OP
       2019-05-15 11:58:17 +08:00
    @dinjufen 谢啦,我去拜读下
    wisefree
        46
    wisefree  
    OP
       2019-05-15 11:59:12 +08:00
    @BingoXuan 嗯,zmq 我在 google 中搜到了,感谢
    wisefree
        47
    wisefree  
    OP
       2019-05-15 11:59:36 +08:00
    wisefree
        48
    wisefree  
    OP
       2019-05-15 12:00:51 +08:00
    @ipwx 好是好,这些名词组合起来,还是有点难的。我要消化下 ->_->
    xiaoyaocmx
        49
    xiaoyaocmx  
       2019-05-15 13:15:30 +08:00 via Android   ❤️ 1
    @wisefree 没有诶
    wisefree
        50
    wisefree  
    OP
       2019-05-15 13:31:33 +08:00
    @xiaoyaocmx 请问有 zmq 的学习资料推荐么?
    est
        51
    est  
       2019-05-15 13:48:30 +08:00   ❤️ 1
    > 使用海康威视摄像头,官方给了很全的代码范例,包括 C++、Java、C#

    好奇这些语言最后也是通过网络协议和摄像头通信的吧?应该有人 hack 出来 py 版本的了。
    guiqiqi
        52
    guiqiqi  
       2019-05-15 14:10:25 +08:00 via iPhone   ❤️ 1
    楼主可以考虑用 Boost::Python 封装接口,工作量不很大,我最近的项目涉及到性能敏感的部分正在用 C++剥离,就用的这个方案
    Raymon111111
        53
    Raymon111111  
       2019-05-15 14:12:37 +08:00   ❤️ 1
    老老实实用 RPC 框架

    比如 gRPC
    JerryV2
        54
    JerryV2  
       2019-05-15 15:11:52 +08:00   ❤️ 1
    用 C++ 调用 Python,很容易的,图片存储成文件,调用时传文件名就行了
    YouXia
        55
    YouXia  
       2019-05-15 15:13:26 +08:00   ❤️ 1
    管道、消息队列、信号量、共享内存等等,进程间通信方式那么多。。
    wisefree
        56
    wisefree  
    OP
       2019-05-15 15:21:48 +08:00
    @est Java 和 C#通过官方的 dll,来获取图像的
    wisefree
        57
    wisefree  
    OP
       2019-05-15 16:36:51 +08:00
    @guiqiqi thanks,:)
    wisefree
        58
    wisefree  
    OP
       2019-05-15 16:37:43 +08:00
    @Raymon111111 嗯嗯,正在找资料学习了解,请问有推荐的资料么?
    wisefree
        59
    wisefree  
    OP
       2019-05-15 16:38:16 +08:00
    @JerryV2 文件读取效率有点低
    wisefree
        60
    wisefree  
    OP
       2019-05-15 16:39:13 +08:00
    @YouXia 惭愧,以前只用过一种语言的进程通信,比如 Python 进程间的通信
    zhuangzhuang1988
        61
    zhuangzhuang1988  
       2019-05-15 16:50:59 +08:00   ❤️ 1
    用这个 试试
    https://github.com/pybind/pybind11
    不过得要好的 c++编译器
    RealMadrid
        62
    RealMadrid  
       2019-05-15 17:15:22 +08:00   ❤️ 1
    可以试下用 c++写相机库,再用 swig 转换为 python 调用的库
    ysc3839
        63
    ysc3839  
       2019-05-15 19:10:50 +08:00 via Android   ❤️ 1
    建议使用 pybind11 而不是 boost.python,前者更加容易配置编译。
    wisefree
        64
    wisefree  
    OP
       2019-05-15 22:20:31 +08:00
    wisefree
        65
    wisefree  
    OP
       2019-05-15 22:20:53 +08:00
    @RealMadrid 谢谢提供思路
    helloworld000
        66
    helloworld000  
       2019-05-16 05:01:57 +08:00   ❤️ 1
    之前做过一个 protobuf + opencv + zeromq,这是 microservice 的思路,其实更符合互联网公司主流。
    pybind11 这种弄成 library 给别人用也不是不可以,学院风更重一点

    都不难
    wisefree
        67
    wisefree  
    OP
       2019-05-16 08:09:03 +08:00
    @helloworld000 很 nice !谢谢啦
    gaoyadianta
        68
    gaoyadianta  
       2019-05-16 13:01:05 +08:00   ❤️ 1
    你用的什么 rtps 实现方案,你列出来的方案中,哪个能有 rtps 快?
    最便捷的:IPC (要速度快用共享内存)
    其次 fast rtps ( 16k 字节延时在 us 级)
    再次之才是什么网络通信,什么 rpc
    gaoyadianta
        69
    gaoyadianta  
       2019-05-16 13:02:25 +08:00   ❤️ 1
    对了 fastrtps 没有 python 实现,,,尴尬
    序列化+共享内存爽的一批
    wisefree
        70
    wisefree  
    OP
       2019-05-16 19:01:38 +08:00
    @gaoyadianta 海康威视官方的 rtps 网址,用 rtps 自带延时 3s 左右
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5255 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 07:16 · PVG 15:16 · LAX 23:16 · JFK 02:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.