我已经在python中包装了一个c库和c API,并调用了必要的DLL。但是,我无法访问存储在union中的数据。
这是我的包装库看起来像一个例子(缩短为convienence):
import ctypes
from ctypes import *
import pandas as pd
class Data(Union):
_fields_ = [
('A', POINTER(ctypes.c_ubyte)),
('B', POINTER(ctypes.c_float))]
class Parm(Structure):
pass
class File(Structure):
pass
Parm._fields_ = [
('parent', ctypes.POINTER(File)),
('name', ctypes.c_char_p),
('data', POINTER(Data)),
('time', ctypes.POINTER(ctypes.c_float)),
File._fields_ = [
('name', ctypes.c_char_p),
('header', ctypes.POINTER(Header)),
('fileInfo', ctypes.POINTER(FileInfo)),
MultiF = (b'path_to_file')
dll = CDLL('path_to_dll')
#read functions
dll.openFile.argtypes = (c_char_p,)
dll.openFile.restype = POINTER(File)
dll.freeFile.argtypes = POINTER(File),
dll.freeFile.restype = int
F = dll.openFile(MultiF) # Pointer to File
ParmName = ctypes.c_char_p(b'parameter_name')
beginTime = ctypes.c_double(-3.4**38)
endTime = ctypes.c_double(3.4**38)
DT_FLOAT = 0x0001
DT_RETURNGMT = 0x0100
convertType = (DT_FLOAT|DT_RETURNGMT)
#retrieve parameter data
dll.readParm.argtypes = POINTER(File), c_char_p, c_double, c_double, POINTER(c_double), POINTER(TTag), c_ushort,
dll.readParm.restype = POINTER(Parm)
dll.freeParm.argtypes = POINTER(Parm),
dll.freeParm.restype = int
g = dll.readParm(F, ParmName, beginTime, endTime, None, None, convertType)
我可以使用此指针检索时间值的位置:
(g[0].time)
返回:
<ctypes.wintypes.LP_c_float at 0x218f044aec8>
当我想检索数据值的位置时,我输入:
(g[0].data[0].B)
返回:
<ctypes.wintypes.LP_c_float at 0x218f044a9c8>
现在我想要实际的时间和数据值,所以我创建了一个for循环,它应该打印出每个时间值和相应的数据 当时的价值。
这是我的for循环:
x = []
y = []
for i in range(0, 1033):
x.append(g[0].time[i])
y.append(g[0].data[0].B[i])
df = pd.DataFrame({'Time': x, 'Data': y})
df
但是这会让Python崩溃,但是'崩溃'我的意思是弹出一个框,说Python现在不再工作了。
所以我试图弄清楚问题是什么,我发现了这个: 我可以单独打印所有时间值
print(g[0].time[0])
print(g[0].time[1]) #.....
返回:
7.304020881652832
7.352021217346191
这些值是正确的,所以我尝试使用数据值:
print(g[0].data[0].B[1])
这就是我得到的,因为崩溃的python。
崩溃python的行是指向包含所有数据值的Union中的float的指针。
我做错了什么?如何在不崩溃Python的情况下从我的联盟中获取数据?
这是我对Parm和Data的C代码:
#define CBASED
#ifdef MAKEDLL
# define DLLEXP __declspec( dllexport )
//# define CBASED
# define CALLCONV
#else
/* using .H file for application */
# define DLLEXP
/* ANSI C program */
# ifdef __STDC__
//# define CBASED
# define CALLCONV
# else
/* C++ program */
//# define CBASED extern "C"
# define CALLCONV _cdecl
# endif
#endif
//union Data
//{
// unsigned char *A; /* generic byte pointer 1 byte */
// float *B; /* generic float pointer 4 byte */
//CBASED DLLEXP struct Parm
//{
// struct File *parent; /* parent file of parameter */
// char *name, /* parameter name */
// union Data data; /* pointers to data buffer */
// float *time; /* time points */