【问题标题】:Call a Python function from C and consume a 2D Numpy array in C从 C 调用 Python 函数并在 C 中使用 2D Numpy 数组
【发布时间】:2019-12-06 10:09:31
【问题描述】:

我在想,我怎么能做到这一点:

我有一个 Python 脚本,它最终会生成一个 Numpy 数组,更具体地说,它是一个浮点数组的数组。我已经正确设置:我可以将参数从 C 传递到 Python,从 C 启动 Py 函数,并在 C 中处理返回的标量值。

我目前无法做的是将这样一个 Numpy 数组作为 Py 函数的结果返回给 C。

有人可以给我一个指针,如何实现这一点?

TIA

【问题讨论】:

  • 你能展示一下你到目前为止所尝试的吗?
  • “将这样的 Numpy 数组作为 Py 函数的结果返回给 C”是什么意思?将返回的numpy数组存储到float-s的数组中?
  • 你能用一个简短的例子来说明你到底想要实现什么吗?如果我理解正确,您需要将从 C 程序调用的 python 函数的输出存储到一些 C 变量中,对吗?
  • 感谢所有 cmets。 @RahulBharadwaj:现在我什么都没试过,因为我不知道。我只能从 python 返回一个标量。基本上它是一个 python 级别的列表,一个包含 192 个列表的列表,每个列表有 640 个浮点数,我需要将其传递给 C

标签: python c arrays numpy


【解决方案1】:

您需要查看的是进程间通信 (IPC)。有几种方法可以执行它。

您可以使用以下之一:

  • 文件(易于使用)
  • 共享内存(非常快)
  • 命名管道
  • 套接字(慢)

请参阅 Wikipedia's IPC page 并找到满足您需求的最佳方法。

【讨论】:

【解决方案2】:

这是一个小的工作演示示例(一维数组,不是二维数组!它并不完美,请根据您的需要进行调整)。

# file ./pyscript.py
import numpy as np

# print inline
np.set_printoptions(linewidth=np.inf)
x = np.random.random(10)
print(x)
# [0.52523722 0.29053534 0.95293405 0.7966214  0.77120688 0.22154705 0.29398872 0.47186567 0.3364234  0.38107864]

~demo.c

// file ./demo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
        int fd[2];
        pipe(fd); // create pipes
        char buf[4096];

        pid_t pid=fork();
        if (pid==0) { // child process

                dup2(fd[1],1);
                close(fd[0]);
                close(fd[1]);

                char *pyscript = "./pyscript.py";
                char *args[] = {"python3", pyscript, (char*)NULL};
                execv("/usr/bin/python3",args);

        }
        else {
                int status;
                close(fd[1]);
                int bytes = read(fd[0], buf, sizeof(buf));
                printf("Python script output: %.*s\n", bytes, buf);

                char* values[10];
                int count = 0;
                values[count++] = &buf[1]; // ignore the '[' coming from numpy array output
                char* p = buf;
                while (*p) {
                        if (*p == ' ') {
                                *p = 0;
                                values[count++] = p + 1;
                        }
                        p++;
                }

                float a[10];
                float f;
                for (int i = 0; i < 10; i++) {
                        printf("%f\n", f = atof(values[i]) ); // float values
                        a[i] = f;
                }

                waitpid(pid, &status, 0);
        }
        return 0;
}

样本输出

# cc demo.c
# ./a.out
Python script output: [0.23286839 0.54437959 0.37798547 0.17190732 0.49473837 0.48112695 0.93113395 0.20877592 0.96032973 0.30025713]

0.23286839
0.54437959
0.232868
0.544380
0.377985
0.171907
0.494738
0.481127
0.931134
0.208776
0.960330
0.300257

a 将是您想要的结果,float 的数组。

【讨论】:

  • 谢谢,但这不是我想要的。
【解决方案3】:

必须使用 PyList API 将列表对象从 Python 解码为 C

https://docs.python.org/3.3/c-api/list.html?highlight=m

解决了。

【讨论】:

    猜你喜欢
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 2017-08-26
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 2013-08-30
    相关资源
    最近更新 更多