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

请教 C++ Python 进程间通信

  •  
  •   wisefree · 11 天前 · 2894 次点击

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

    目前的粗略想法

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

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

    注:

    • 不只一个摄像头,可能有 4 个以上
    • 为什么不全程用 C++,因为要用到 Python 中的一些库
    • 不用 rstp 协议,因为它延时太高
    第 1 条附言  ·  10 天前

    谢谢各位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
        1
    CSM   11 天前 via Android   ♥ 1
    Python 起一个 HTTP 服务器,C++每得到一个图片就 post 过去?(我猜的)
        2
    bsidb   11 天前   ♥ 2
    gRPC
        3
    Leigg   11 天前 via iPhone   ♥ 1
    你是想在内存中直接将图片流传给 python 吧
    C++是可以调用 python 函数的,你找一下相关资料吧
    这里有一个不是很详细但肯定需要折腾会儿
    https://mp.weixin.qq.com/s/VFYrFB63BKd-W3yaJqE2NQ
    不如 1 楼那样开发快。
        4
    hakono   11 天前 via iPhone   ♥ 1
    相信我别尝试 python 调 dll 或者 c 调用 python
    到时候这种跨语言调用,调试起来告诉你什么叫地狱。。。。

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

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

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

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

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

    都不难
        67
    wisefree   10 天前
    @helloworld000 很 nice !谢谢啦
        68
    gaoyadianta   9 天前   ♥ 1
    你用的什么 rtps 实现方案,你列出来的方案中,哪个能有 rtps 快?
    最便捷的:IPC (要速度快用共享内存)
    其次 fast rtps ( 16k 字节延时在 us 级)
    再次之才是什么网络通信,什么 rpc
        69
    gaoyadianta   9 天前   ♥ 1
    对了 fastrtps 没有 python 实现,,,尴尬
    序列化+共享内存爽的一批
        70
    wisefree   9 天前
    @gaoyadianta 海康威视官方的 rtps 网址,用 rtps 自带延时 3s 左右
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2220 人在线   最高记录 5043   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 26ms · UTC 05:00 · PVG 13:00 · LAX 22:00 · JFK 01:00
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1