如何将 python 字典发送到 C++
How to send python dict to C++
- 这是我的 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++ 函数,我想在其中使用字典作为数组
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);
}
- My objective 接受来自 python 函数的字典值,并将其转换为适合包装器中 C 的数组值。我没有 C\C++ 的先验知识,我被卡住了。任何帮助都会有很大帮助。谢谢
您可能需要包括 dictobject.h、floatobject.h、,如果尚未通过其他 headers 引入。这是一种将所有值从浮点数字典中获取到向量的方法。根据字典中的实际内容以及它的结构,您可能需要查看键和其他部分。
请注意,这是 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, ¤tVal) {
// 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?
}
- 这是我的 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++ 函数,我想在其中使用字典作为数组
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);
}
- My objective 接受来自 python 函数的字典值,并将其转换为适合包装器中 C 的数组值。我没有 C\C++ 的先验知识,我被卡住了。任何帮助都会有很大帮助。谢谢
您可能需要包括 dictobject.h、floatobject.h、,如果尚未通过其他 headers 引入。这是一种将所有值从浮点数字典中获取到向量的方法。根据字典中的实际内容以及它的结构,您可能需要查看键和其他部分。 请注意,这是 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, ¤tVal) {
// 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?
}