【问题标题】:How do I connect a Python and a C program?如何连接 Python 和 C 程序?
【发布时间】:2011-01-20 05:29:10
【问题描述】:

我有一个基于 python 的程序,可以从连接到 rs232 电缆的端口读取串行数据。我想将我在这里得到的数据传递给一个 C 程序,该程序将处理计算密集型的事情。我上网查了一下,发现都是基于linux的。

【问题讨论】:

  • “我发现的都是基于 linux 的”...我猜这意味着你没有使用 Linux。您使用的是什么操作系统

标签: python c


【解决方案1】:

我的建议是instant 模块中的inline 函数,但只有在你可以在单个c 函数中完成所需的一切时才有效。您只需将一个 c 函数传递给它,它就会在运行时编译一个 c 扩展。

    from instant import inline
    sieve_code = """
    PyObject* prime_list(int max) {
        PyObject *list = PyList_New(0);
        int *numbers, *end, *n; 
        numbers = (int *) calloc(sizeof(int), max);
        end = numbers + max;

        numbers[2] = 2;
        for (int i = 3; i < max; i += 2) { numbers[i] = i; }
        for (int i = 3; i < sqrt(max); i++) {
            if (numbers[i] != 0) {
                for (int j = i + i; j < max; j += i) { numbers[j] = 0; }
            }
        }
        for (n = numbers; n < end; n++) { 
            if (*n != 0) { PyList_Append(list, PyInt_FromLong(*n)); }
        }
        free(numbers);
        return list;
    }
    """
    sieve = inline(sieve_code)

【讨论】:

【解决方案2】:

有很多方法可以做到这一点。

  1. 最原始、最简单的方法是使用 Python C API 并为您的 C 库编写一个可以从 Python 调用的包装器。这会将您的模块与 CPython 联系起来。

  2. 第二种方法是使用ctypes,它是Python 的FFI,允许您直接加载和调用C 库中的函数。理论上,这应该适用于 Python 实现。

  3. 第三种方法是使用Pyrex 或它的下一代版本Cython,它允许您使用编译器可以转换为编译代码的类型信息来注释您的Python 代码。它也可以用来编写包装器。 AFAIK,它与 CPython 相关。

  4. 还有一种方法是使用SWIG,它是一种生成胶水代码的工具,可帮助您包装 C 库以供 Python 使用。它基本上是第一种使用辅助工具的方法。

  5. 另一种方法是使用Boost Python API,它是原始 Python C API 上的面向对象的包装器。

以上所有方法都可以让您在同一个过程中完成工作。

如果这不是一个约束,就像Digital Ross 建议的那样,您可以简单地生成一个子进程并交出参数(作为命令行参数或通过它的标准输入)并让一个外部进程为您完成工作。

【讨论】:

  • 哪一个最快?
  • 我不完全确定,因为我自己没有测量过它们,但我会先使用cffi,如果不够快,请直接使用 C API(尽管这样可以我到单个 Python 实现)。
【解决方案3】:

使用管道并弹出

处理这个问题的最简单方法可能就是使用popen(3)popen 函数在 Python 和 C 中都可用,它将使用管道将任何一种语言的程序与另一种语言的程序连接起来。

>>> import subprocess
>>> print args
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args)

一旦你有了管道,你可能应该通过它发送 yaml 或 json,尽管我从未尝试在 C 中读取它们。如果它真的是一个简单的流,你自己解析它。如果你喜欢 XML,我想这也是可用的。

【讨论】:

  • 这也适用于 Windows 吗?
  • 它有效,尽管不完全相同。来自 Python 手册: 在 Windows 上:Popen 类使用 CreateProcess() 来执行子程序,该程序对字符串进行操作。如果 args 是一个序列,它将使用 list2cmdline() 方法转换为字符串。请注意,并非所有 MS Windows 应用程序都以相同的方式解释命令行:list2cmdline() 是为使用与 MS C 运行时相同规则的应用程序设计的。
  • 这可能很明显,但是只有发送者使用popen,接收过程只是正常的get*、read、fread等等。
【解决方案4】:

您通过这条 RS-232 电缆每秒传输多少比特?你有没有测试结果表明 Python 不能足够快地完成脆脆的位?如果尚未编写 C 程序,请考虑使用 Python 编写计算密集型事物的可能性,如果 Python 速度不够快,可以轻松回退到 Cython

【讨论】:

    【解决方案5】:

    确实,这个问题与 C++ 没有太大关系。 话虽如此,你可以试试SWIG - 它是多平台的,允许从 Python 到 C/C++ 的函数调用。

    【讨论】:

      【解决方案6】:

      我会使用标准形式的 IPC,例如套接字。

      Beej's Guide. 是一个好的开始

      另外,如果您专门使用 c,请不要用 c++ 标记问题。 c 和 c++ 是不同的语言。

      【讨论】:

        【解决方案7】:

        我会使用 ctypes:http://python.net/crew/theller/ctypes/tutorial.html
        它允许您从 python 调用 c(和 c++)代码。

        【讨论】:

          猜你喜欢
          • 2014-09-18
          • 1970-01-01
          • 2020-08-05
          • 1970-01-01
          • 2018-07-14
          • 1970-01-01
          • 1970-01-01
          • 2019-03-08
          • 2015-02-06
          相关资源
          最近更新 更多