从Union类获取数据会导致Python崩溃

2024-10-02 12:33:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经用python包装了一个c库和c API,并调用了必要的DLL。但是我在访问存储在union中的数据时遇到了问题。你知道吗

这是我的包装库外观的一个示例(为了方便起见,将其缩短):

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崩溃的行是一个指针,指向保存所有数据值的联合中的一个浮点。你知道吗

我的问题是:

我做错了什么?如何才能在不破坏Python的情况下从这个联合体中获取数据?你知道吗

这是我为参数和数据准备的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                 */

Tags: 数据namedatatimefloatctypesfiledll

热门问题