简体   繁体   English

如何连接Python和C程序?

[英]How do I connect a Python and a C program?

I have a python-based program that reads serial data off an a port connected to an rs232 cable. 我有一个基于python的程序,从连接到rs232电缆的端口读取串行数据。 I want to pass the data I get here to a C-program that will handle the computation-intensive side of things. 我想把我在这里得到的数据传递给一个C程序,它将处理计算密集型的一面。 I have been checking up the net and all I've found are linux-based. 我一直在检查网络,我发现的都是基于Linux的。

My suggestion would be the inline function from the instant module, though that only works if you can do everything you need to in a single c function. 我的建议是instant模块的inline函数,但只有在单个c函数中可以完成所需的一切时才能使用。 You just pass it ac function and it compiles ac extension at runtime. 你只需传递它的ac函数,它就会在运行时编译ac扩展。

    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)

There a number of ways to do this. 有很多方法可以做到这一点。

  1. The rawest, simplest way is to use the Python C API and write a wrapper for your C library which can be called from Python. 最简单的方法是使用Python C API并为C库编写一个可以从Python调用的包装器。 This ties your module to CPython. 这将您的模块与CPython联系起来。

  2. The second way is to use ctypes which is an FFI for Python that allows you to load and call functions in C libraries directly. 第二种方法是使用ctypes ,它是Python的FFI ,允许您直接加载和调用C库中的函数。 In theory, this should work across Python implementations. 从理论上讲,这应该适用于Python实现。

  3. A third way is to use Pyrex or it's next generation version Cython which allows you to annotate your Python code with type information that the compiler can convert into compiled code. 第三种方法是使用Pyrex或它的下一代版本Cython ,它允许您使用编译器可以转换为编译代码的类型信息来注释您的Python代码。 It can be used to write wrappers too. 它也可以用来编写包装器。 AFAIK, It's tied to CPython. AFAIK,它与CPython有关。

  4. Yet another way is to use SWIG which is a tool that generates glue code that helps you wrap C libraries for use from Python. 另一种方法是使用SWIG ,它是一种生成粘合代码的工具,可帮助您包装C库以供Python使用。 It's basically the first approach with a helper tool. 它基本上是第一种使用辅助工具的方法。

  5. Another way is to use Boost Python API which is an object oriented wrapper over the raw Python C API. 另一种方法是使用Boost Python API ,它是一个面向对象的原始Python C API包装器。

All of the above let you do your work in the same process. 以上所有内容都可以让您在同一个过程中完成工作。

If that's not a constraint, like Digital Ross suggested, you can simply spawn a subprocess and hand over arguments (either as command line ones or via it's standard input) and have an external process do the work for you. 如果这不是一个约束,就像Digital Ross建议的那样,你可以简单地生成一个子进程并移交参数(作为命令行或通过它的标准输入)并让外部进程为你工作。

Use a pipe and popen 使用管道和popen

The easiest way to deal with this is probably to just use popen(3) . 解决这个问题的最简单方法可能就是使用popen(3) The popen function is available in both Python and C and will connect a program of either language with the other using a pipe. popen函数在Python和C中都可用,并且将使用管道将任一语言的程序与另一种语言连接。

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

Once you have the pipe, you should probably send yaml or json through it, though I've never tried to read either in C. If it's really a simple stream, just parse it yourself. 一旦你有管道,你应该通过它发送yaml或json,虽然我从来没有试过在C中读取。如果它真的是一个简单的流,只需自己解析。 If you like XML, I suppose that's available as well. 如果您喜欢XML,我想也可以使用它。

How many bits per second are you getting across this RS-232 cable? 这条RS-232电缆每秒钟有多少位? Have you test results that show that Python won't do the crunchy bits fast enough? 您是否测试过显示Python不会足够快地执行嘎嘎声的结果? If the C program is yet to be written, consider the possibility of writing the computation-intensive side of things in Python, with easy fallback to Cython in the event that Python isn't fast enough. 如果尚未编写C程序,请考虑在Python中编写计算密集型方面的可能性,如果Python不够快,可以轻松回退到Cython

Indeed this question does not have much to do with C++. 实际上,这个问题与C ++没什么关系。 Having said that, you can try SWIG - it's multi-platform and allows functional calls from Python to C/C++. 话虽如此,您可以尝试SWIG - 它是多平台的,允许从Python到C / C ++的函数调用。

I would use a standard form of IPC like a socket. 我会像插座一样使用标准形式的IPC。

A good start would be Beej's Guide. 一个好的开始是Beej的指南。

Also, don't tag the question with c++ if you are specifically using c. 另外,如果您专门使用c,请不要使用c ++标记问题。 c and c++ are different languages. c和c ++是不同的语言。

I'd use ctypes: http://python.net/crew/theller/ctypes/tutorial.html 我使用ctypes: http//python.net/crew/theller/ctypes/tutorial.html
It allows you to call c (and c++) code from python. 它允许您从python中调用c(和c ++)代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM