【问题标题】:How to send python dict to C++如何将python dict发送到C++
【发布时间】:2020-12-12 09:35:41
【问题描述】:
  • 这是我的 python 函数:
if __name__ == "__main__":
    file = open("data_input.txt", "r")
    contents = file.read()
    e = ast.literal_eval(contents)
    neighbour_num= 4
    new_data = 300
    result = np.ndarray((4,4),dtype='int32',buffer=np.zeros((4,4),dtype='int32'))
    c_module.mmult_wrapper(e, new_data, neighbour_num, result)
  • 这是我的 C++ 函数,我想在其中使用 dict 作为数组
   void mmult(double new_data, double neighbour_num, double e[100], int32_t result[16]) {
   double distances[100];
   unsigned distances_front = 0;
   unsigned distances_back = 0;

   double keys[100];
   unsigned keys_front = 0;
   unsigned keys_back = 0;
 

   for(int i=0;i<(int)100; i=i+1) {

      double temp_distance=(new_data-e[i]);

      double sq_tmp=(temp_distance*temp_distance);

      double sqrt=(sq_tmp/2);

      double temp=0;
      while(sqrt!=temp) {
         temp = sqrt;
         sqrt = (((sq_tmp/temp)+temp)/2);
      }
      distances[distances_front++] = (sqrt);
      keys[keys_front++] = (e[i-1]);
   }
   for(int i=0; i<(int)(keys_front - keys_back); i=i+1) {
      for(int j=(i+1); j<(int)(distances_front - distances_back); j=j+1) {
         if(distances[i]>distances[j]) {
            distances[i] = distances[j];
            distances[j] = distances[i];
            keys[i] = keys[j];
            keys[j] = keys[i];
         }
      }
   }
   for(int i=0; i<(int)neighbour_num; i=i+1) {
      result[i] = keys[i];
   }
} 
  • 这是我的包装函数
#include <Python.h>
#include <numpy/arrayobject.h>
#include "spyc.h"
#include "caller.h"

static PyObject* mmult_wrapper(PyObject* self, PyObject* args) {

   int32_t e;
   int32_t new_data;
   int32_t neighbour_num;
   int32_t result;

   int res = PyArg_ParseTuple(args, "Oi", &e_obj, &d);

   if (!res)
      return NULL;


   /* call function */
   mmult_caller(e,d);

} 

  • 我的目标是接受来自 python 函数的 dict 值并将其转换为适合包装器中 C 的数组值。我没有 C\C++ 的先验知识,我被卡住了。任何帮助都会有很大帮助。谢谢

【问题讨论】:

  • 参见stackoverflow.com/questions/1842941/… 制作地图可能比通过循环将事物转换为数组更合适。甚至boost.org/doc/libs/1_41_0/libs/python/doc/index.html
  • 前段时间,当我需要将一些 Python 代码与 C++ 交互时,我发现 Python 的文档写得很好,有条理,并且告诉我我需要知道的一切。关于这个主题的 Python 大量文档的哪些部分对您来说不是特别清楚?此外,令人不安的是您没有“C\C++ 的先验知识”。 C++ 是当今使用的最复杂的通用编程语言。这种将 C++ 连接到另一种语言的代码已经够难了。在没有对 C++ 基本了解的情况下尝试这样做几乎是不可行的,抱歉。
  • @Abel 我的目标不是使用映射,因为我不能用地图声明大小,因此我试图将其转换为一维数组。
  • @Vivek 所以你只是在寻找stackoverflow.com/questions/16228248/…
  • @Abel 我希望,但我不想在 python 函数中对 dict 执行任何类型的转换。它必须只发生在经纱机中。

标签: c++ arrays c python-3.x wrapper


【解决方案1】:

如果尚未通过其他标头引入,您可能需要包含 dictobject.h、floatobject.h、。这是一种将浮点数的字典中的所有值抓取到向量的方法。根据字典中的实际内容以及它的结构,您可能需要查看键和其他部分。 请注意,这是 C++,因此应该这样编译。


//returns true on success
bool dictToVector(PyObject *  srcDict, std::vector<double> & destVector) {
 destVector.clear();
 if(PyDict_Check(srcDict)) {
  Py_ssize_t numItems = PyDict_Size(srcDict);
  destVector.reserve(numItems);
  Py_ssize_t iteratorPPOS = 0;
  PyObject * currentVal;
  while(PyDict_Next(srcDict, &iteratorPPOS, NULL, &currentVal) {
   // might be worth checking PyFloat_Check...
   destVector.push_back(PyFloat_AsDouble(currentVal));
  }
  return (numItems == destVector.size());
 }
 else { // not a dict return with failure
  return false;
 }
}

最后你的包装器将类似,因为它需要将 mmult 的结果复制到结果类型 numpy.ndarray 中。

上面的用法如下:


PyObject* mmult_wrapper(PyObject * e, PyObject * new_data, PyObject * neighbour_num, PyObject * result) {
 int32_t Cresult[16];
 std::vector<double> Ce;
 bool noErrorSoFar = dictToVector(e,Ce);
 if(Ce.size() == 100) {
  mmult(PyFloat_AsDouble(new_data) , PyFloat_AsDouble( neighbour_num), Ce.data(), Cresult);
 }
else { // not 100 doubles in the data read!
  noErrorSoFar = false;
 }

... //some stuff to copy Cresult to the python, and return something meaningful?
}

【讨论】:

  • 我非常感谢你的帮助。最后一个疑问,你知道这里到底发生了什么“ int res = PyArg_ParseTuple(args, "Oi", &e_obj, &d); " 吗?
  • 这是一种替代方法,可以避免像 PyFloat_AsDouble 这样的调用,并可用于剥离 PyObject 层以获得整个变量列表。在这种情况下,O 和 i 分别表示:将列表中的 first 保留为 PyObject *(对于 e),并将 second 转换为 int 对于 d。请注意,args 应该是所有必要 python 变量的 python 元组(列表)。 docs.python.org/2.0/ext/parseTuple.html
  • 非常感谢您的帮助。
  • 有没有类似的东西可以用于元组和集合。
  • 使用可以迭代元组和集合并获取值的“PyDict_Next(srcDict, &iteratorPPOS, NULL, &currentVal)”的东西
猜你喜欢
  • 2019-05-08
  • 1970-01-01
  • 1970-01-01
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
  • 2021-05-24
相关资源
最近更新 更多