我有一个包含以下条目的Python字典:
Tmp={'Name1': [10.0, 20.0, 'Title1', 1], 'Name2': [5.0, 25.0, 'Title2', 2]}
我想将它传递给C函数,函数定义为:
struct CA {
char *Keys;
float *Values;
char *Title;
int Index;
};
void myfunc (struct CA *in, int n);
在Python方面,我创建了一个等效的ctypes结构:
class CA(ctypes.Structure):
_fields_ = [("Keys", ctypes.POINTER(ctypes.c_char_p)),
("Values", ctypes.POINTER(ctypes.c_float)),
("Title", ctypes.POINTER(ctypes.c_char_p)),
("Index", ctypes.c_int)]
并使用以下方法创建了一个CA数组:
CAarray = CA * 2
现在我想在一个循环中将Tmp分配给CAarray,以便
k = Tmp.keys()
for (j, _) in enumerate(k):
CAarray[j].Keys = _
CAarray[j].Values = Tmp[_][:2]
CAarray[j].Title = Tmp[_][2]
CAarray[j].Index = Tmp[_][3]
我一直在努力使语法正确,并且到目前为止都失败了。帮助
另一方面,是否有任何例程/ lib可以处理Python变量和ctypes变量之间的转换?
答案 0 :(得分:4)
我创建了一个测试DLL来验证结构是否正确传递。
#include <stdio.h>
struct CA {
char *Keys;
float *Values;
char *Title;
int Index;
};
__declspec(dllexport) void myfunc (struct CA *in, int n)
{
int i;
for(i = 0; i < n; ++i)
{
printf("%d: Keys = %s\n",i,in[i].Keys);
printf("%d: Values = %f %f\n",i,in[i].Values[0],in[i].Values[1]);
printf("%d: Title = %s\n",i,in[i].Title);
printf("%d: Index = %d\n",i,in[i].Index);
}
}
以下是我的称呼方式:
#!python3
from ctypes import *
class CA(Structure):
_fields_ = [('Keys',c_char_p),
('Values',POINTER(c_float)),
('Title',c_char_p),
('Index',c_int)]
Tmp={'Name1': [10.0, 20.0, 'Title1', 1], 'Name2': [5.0, 25.0, 'Title2', 2]}
# repackage Tmp as a list of CA structures
ca_list = []
for k,v in Tmp.items():
ca = CA()
ca.Keys = k.encode('utf8') # Python 3 strings are Unicode, char* needs a byte string
ca.Values = (c_float*2)(v[0],v[1]) # Interface unclear, how would target function know how many floats?
ca.Title = v[2].encode('utf8')
ca.Index = v[3]
ca_list.append(ca)
# repackage python list of CAs to ctype array of CAs
ca_array = (CA * len(ca_list))(*ca_list)
dll = CDLL('test')
dll.myfunc.argtypes = POINTER(CA),c_int
dll.myfunc.restype = None
dll.myfunc(ca_array,len(ca_array))
输出:
0: Keys = Name1
0: Values = 10.000000 20.000000
0: Title = Title1
0: Index = 1
1: Keys = Name2
1: Values = 5.000000 25.000000
1: Title = Title2
1: Index = 2
答案 1 :(得分:0)
不完全确定这一点,但似乎有效:
tmp = {'Name1': [10.0, 20.0, 'Title1', 1], 'Name2': [5.0, 25.0, 'Title2', 2]}
class CA(ctypes.Structure):
_fields_ = [("key", ctypes.POINTER(ctypes.c_wchar_p)),
("values", ctypes.POINTER(ctypes.c_float)),
("title", ctypes.POINTER(ctypes.c_wchar_p)),
("index", ctypes.c_int)]
CAArray = CA * 2
ca_array = CAArray()
for ca, key in zip(ca_array, tmp):
ca.key = ctypes.pointer(ctypes.c_wchar_p(key))
ca.values = ctypes.pointer(ctypes.c_float(tmp[key][0]))
ca.title = ctypes.pointer(ctypes.c_wchar_p(tmp[key][2]))
ca.index = tmp[key][3]
for ca in ca_array:
print(ca.key[0], ca.values[0], ca.values[1], ca.title[0], ca.index)
我坚持使用Python命名约定。