python 调用c++程序, c++程序如何返回数组给python

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 调用c++程序, c++程序如何返回数组给python相关的知识,希望对你有一定的参考价值。

比如python调用一个c++程序,c++程序里定义一个数组float x[5] = 1,2,3,4,5,最后要把这个数组返回到python,要怎么做呢?
目前找到的例子都是把cpp文件编译成.so文件,然后在python里用ctypes调用。试了一下发现如果c++返回一个值,是可以的。但不知道要怎么返回数组。
先谢过各位大神了!!!

C/C++不能直接返回一个数组。这是由于在C/C++中,数组不是一种类型,因此不能被直接返回。
一般有两种方法来返回一个数组。
第一种方法:
返回一个指向数组的指针,例如char (*retArray)[10]声明了一个函数retArray,该函数可以返回指向具有10个char元素的数组
第二种方法:
如果你不喜欢用指针的形式返回数组,那么可以采用返回一个结构的形式。这种形式相对较安全,可以避免忘记释放指针而造成内存泄露,也可以避免访问悬挂指针造成的错误。但缺点是由于结构是先拷贝再返回,因此如果结构较大时,会影响效率和占用较大内存。
这是C的限制,Python调用C也是这种情况
参考技术A 你说的调用是指什么,单纯拿标准输出的结果?
那你得吧数据以一些格式当成字符串输出,然后再用python解析字符串还原成你需要的格式。

如何将数组从 c++ 传递给 python 函数并将 python 返回的数组检索到 c++

【中文标题】如何将数组从 c++ 传递给 python 函数并将 python 返回的数组检索到 c++【英文标题】:how to pass an array from c++ to python function and retrieve python returned array to c++ 【发布时间】:2012-03-29 09:40:49 【问题描述】:

我正在编写一个 c++ 程序来调用 python 函数并检索返回数组。但我总是收到如下错误:

只有长度为 1 的数组可以转换为 Python 标量

和我的 C++ 代码:

 int main(int argc, char *argv[])

    int i;
    PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue;

    if (argc < 3) 
    
        printf("Usage: exe_name python_source function_name\n");
        return 1;
    

    // Initialize the Python Interpreter
    Py_Initialize();

    // Build the name object
    pName = PyString_FromString(argv[1]);

    // Load the module object
    pModule = PyImport_Import(pName);

    // pDict is a borrowed reference 
    pDict = PyModule_GetDict(pModule);

    // pFunc is also a borrowed reference 
    pFunc = PyDict_GetItemString(pDict, argv[2]);

    if (PyCallable_Check(pFunc)) 
    
        // Prepare the argument list for the call
        if( argc > 3 )
        
                pArgs = PyTuple_New(argc - 3);
                for (i = 0; i < argc - 3; i++)
                
                    pValue = PyInt_FromLong(atoi(argv[i + 3]));
                    if (!pValue)
                    
                        PyErr_Print();
                        return 1;
                    
                    PyTuple_SetItem(pArgs, i, pValue);  
                

                pValue = PyObject_CallObject(pFunc, pArgs);

                if (pArgs != NULL)
                
                    Py_DECREF(pArgs);
                
         else
        
                pValue = PyObject_CallObject(pFunc, NULL);
        

        if (pValue != NULL) 
        
            cout <<pValue;
            printf("Return of call : %ld\n", PyInt_AsLong(pValue));
            PyErr_Print();
            Py_DECREF(pValue);
        
        else 
        
            PyErr_Print();
        
     else 
    
        PyErr_Print();
    

    // Clean up
    Py_DECREF(pModule);
    Py_DECREF(pName);

    // Finish the Python Interpreter
    Py_Finalize();

    system("PAUSE");
    return 0;

Python 函数:

 import numpy as np
    _ZERO_THRESHOLD = 1e-9      # Everything below this is zero
def data():
    print "process starting..."
    N = 5
    obs = np.matrix([np.random.normal(size=5) for _ in xrange(N)])              
    V = pca_svd(obs)
    print "V:"
    print V[0:5]

    pca = IPCA(obs.shape[1], 3)
    for i in xrange(obs.shape[0]):
        x = obs[i,:].transpose()
        print " "
        print "new input:"
        print x
        pca.update(x)

    U = pca.components
    A = pca.variances
    B = U.T*x
    print B
    return B

我知道这句话有问题

PyInt_AsLong(pValue) 谁能告诉我如何解决这个问题,以便将矩阵从 python 检索到 c++

非常感谢。

【问题讨论】:

研究这个应该会有所帮助:scipy.org/Cookbook/C_Extensions/NumPy_arrays @JanneKarila 看起来链接已更改。这就是你的意思:scipy-cookbook.readthedocs.org/items/…? @dbliss 是的,就是这样。 【参考方案1】:

您正在使用 PyInt_AsLong(pValue) 将 Python 对象 pValue 转换为 C long 标量。如果pValue 是一个 Numpy 数组,这意味着您正在尝试将数组转换为数字,这仅适用于长度为 1 的数组:

只有长度为 1 的数组可以转换为 Python 标量

不使用PyInt_AsLong,而是使用Numpy's C API提供的PyArray_*函数来访问数据;特别是,请参阅Array API 部分。

【讨论】:

如果你在这里提供一个最小的例子就好了,但是 +1 表示正确的方向。【参考方案2】:

您想使用 NumPy C API,可能是为了获取数据指针

#include <numpy/arrayobject.h>
...
p = (uint8_t*)PyArray_DATA(pValue);

在确定您确实获得了正确尺寸的数组之后。有关示例代码,请参阅我的hello.hpp。

【讨论】:

以上是关于python 调用c++程序, c++程序如何返回数组给python的主要内容,如果未能解决你的问题,请参考以下文章

从 C++ 调用 Python

如何将值从python传递给c++并返回?

用c++调用python程序

从 C++ 调用 python 函数时如何将 C++ 类作为参数传递?

使用 SWIG 将 C++ 对象指针传递给 Python,而不是再次返回 C++

部署嵌入了python的C++程序