将许多数据从Python传递到C程序

2024-06-10 14:35:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python脚本和一个C程序,我需要从Python脚本传递大量数据,这些数据多次调用C程序。现在,我让用户在使用ASCII文件或二进制文件传递它们之间进行选择,但这两个文件都非常慢而且没有用处(我的意思是,如果要存储数据,文件很有用,但我在脚本末尾删除了这些文件)。

os.system不起作用,参数太多,因为C程序太多地使用文件将数据返回到Python,但这是更少的数据。

我想知道我能用什么来加快这次交易。将文件写入RAM磁盘?如果是,我该怎么做?

我听说可以使用ctypes从DLL调用函数,但不知道如何将程序编译为DLL(我在Windows764上使用wxdevc+)。 或者把它包起来,但仍然不知道它是否能工作,是否有效。

这些数据是三维网格的顶点。

我在另一个程序(blender(开源)中运行Python脚本,由于它在一个周期内,所以被多次调用(通常超过500次)。脚本向程序发送顶点信息(1int索引和3个浮点坐标),程序应该返回许多顶点(只有int index,因为我可以用Python找到对应的顶点)。

所以这不是交互式的,更像是一个函数(但它是用C编写的)。我正在编写的script+C程序(blender的附加组件)应该是跨平台的,因为它将被重新分发。

程序实际上是用C编写的,从Python中我可以知道包含顶点数据的结构的内存地址。如果只有我知道如何做到这一点,应该更好地传递给C程序只有一个地址,并从那里找到所有其他顶点(都存储在列表中)。

但据我所知,我无法访问另一个程序的内存空间,我也不知道是用管道调用程序,还是用什么初始化一个新线程,还是在脚本中运行(实际上是在Blender线程下运行)

Here is the sourceblender/source/blender/makesdna/DNA_meshdata_types.h应该是结构定义


Tags: 文件数据用户程序脚本sourceascii二进制
3条回答

这里有一个与其他方法稍有不同的想法:将C程序编写为Python模块。Here是你做这件事所需要的全部信息。然后,可以在Python代码和C代码之间来回传递大型缓冲区。

管道是显而易见的方法;如果您的c程序接受来自stdin的输入,那么您可以使用Popen。这不会像您在编辑中所说的那样创建一个“线程”;它会创建一个带有单独内存的全新进程:

from subprocess import Popen, PIPE

input = "some input"
cproc = Popen("c_prog", stdin=PIPE, stdout=PIPE)
out, err = cproc.communicate(input)

这里有一个更详细的例子。首先,一个简单的c程序,它与stdin相呼应:

#include<stdio.h>
#include<stdlib.h>
#define BUFMAX 100

int main() {
    char buffer[BUFMAX + 1];
    char *bp = buffer;
    int c;
    FILE *in;
    while (EOF != (c = fgetc(stdin)) && (bp - buffer) < BUFMAX) {
        *bp++ = c;
    }
    *bp = 0;    // Null-terminate the string
    printf("%s", buffer);
}

然后是一个python程序,它将输入(在本例中是从argv)管道传输到上面:

from subprocess import Popen, PIPE
from sys import argv

input = ' '.join(argv[1:])
if not input: input = "no arguments given"
cproc = Popen("./c_prog", stdin=PIPE, stdout=PIPE)
out, err = cproc.communicate(input)
print "output:", out
print "errors:", err

不过,如果您不打算使用没有python前端的c程序,那么最好内联一个c函数,或者使用instant

from instant import inline
c_code = """
    [ ... some c code ... ] //see the below page for a more complete example.
"""
c_func = inline(c_code)

正如Joe指出的,您还可以在c:Extending Python with C or C++中编写一个python模块

这个答案讨论了将c和python结合起来的其他方法:How do I connect a Python and a C program?

编辑:根据您的编辑,听起来您真的应该创建一个cpython扩展。如果你想要一些示例代码,请告诉我;但是一个完整的解释会给出一个不合理的长答案。请参阅上面的链接(扩展Python…)了解您需要知道的一切。

如果您的操作系统支持,named pipes是文件的替换项。

相关问题 更多 >