Python 3.4.3 ctypes:尝试将结构作为输出参数传递给函数失败

时间:2015-04-22 16:41:02

标签: python-3.x ctypes

这是供应商给出的描述功能的内容。

typedef struct
{
   float    distance_sm;
   float    distance_nm;
   short    fuel_stops;
   char     flight_time[8];
   char     block_time[8];
   char     departure_time[8];
   char     departure_date[12];
   char     arrival_time[8];
   char     arrival_date[12];
   char     timezone_change[8];
   char     messages[FOSAPI_MSG_LEN];
} FOS_LEG;

FOS_EXTERN_C bool DLL_EXP_UTIL fos_calc_flight(
   char *leg_date,               // in: leg date                          (
   char *leg_time,              // in: leg time                          (
   char *airport_from,          // in: from airport ICAO(4) or IATA(3)   (KOKC)
   char *airport_to,            // in: to airport ICAO(4) or IATA(3)
   char *aircraft_type,         // in: character aircraft type (max len = 4)
   FOS_LEG  *fos_leg,            // in: allocated space for FOS_LEG
   char errors[FOSAPI_MSG_LEN],         // in: 256 bytes  out: error messages
   bool arrival_date_time=false,    // in: true = leg_date and leg_time are arrival, calculate departure
   char *airport_from_prefix=NULL,  // in: from airport icao code(2)
   char *airport_to_prefix=NULL);   // in: to airport icao code(2)

所以我的代码是我试图访问该功能的。似乎问题在于我试图将结构作为输出参数传递给函数。

import ctypes

mydll = ctypes.windll.LoadLibrary("C:\\FOS\\FosUtil.dll")

class FOS_LEG(ctypes.Structure):
    _fields_ = [
    ("distance_sm",     ctypes.c_float),
    ("distance_nm",     ctypes.c_float),
    ("fuel_stops",      ctypes.c_short),
    ("flight_time",     ctypes.c_char),
    ("block_time",      ctypes.c_char),
    ("departure_time",  ctypes.c_char),
    ("departure_date",  ctypes.c_char),
    ("arrival_time",    ctypes.c_char),
    ("arrival_date",    ctypes.c_char),
    ("timezone_change", ctypes.c_char),
    ("messages",        ctypes.c_char)]

fos_leg   = ctypes.POINTER(FOS_LEG)
error_out = ctypes.c_char

mydll._fos_calc_flight("04042014","0800","KOKC","KATL","H25B",fos_leg,error_out,1,"AP","AP")

这里是返回的错误。

  

回溯(最近一次呼叫最后):文件" test.py",第28行,in          mydll._fos_calc_flight(" 04042014"" 0800"" KOKC"" KATL"" H25B",fos_leg呃   ror_out,1," AP"," AP")ctypes.ArgumentError:参数6 ::不知道如何转换参数6

非常感谢您的帮助

1 个答案:

答案 0 :(得分:3)

未经测试,但您的结构应该更像:

class FOS_LEG(ctypes.Structure):
    _fields_ = [
    ("distance_sm",     ctypes.c_float),
    ("distance_nm",     ctypes.c_float),
    ("fuel_stops",      ctypes.c_short),
    ("flight_time",     ctypes.c_char * 8),
    ("block_time",      ctypes.c_char * 8),
    ("departure_time",  ctypes.c_char * 8),
    ("departure_date",  ctypes.c_char * 12),
    ("arrival_time",    ctypes.c_char * 8),
    ("arrival_date",    ctypes.c_char * 12),
    ("timezone_change", ctypes.c_char * 8),
    ("messages",        ctypes.c_char * FOSAPI_MSG_LEN)]

接下来,您应该声明函数的参数和返回类型:

mydll._fos_calc_flight.argtypes = [ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p,ctypes.POINTER(FOS_LEG),ctypes.c_char_p,ctypes.c_bool,ctypes.c_char_p,ctypes.c_char_p]
mydll._fos_calc_flight.restype = ctypes.c_bool

最后,您的输出参数必须是所需类型的实例POINTER仅声明一个类型,因此您要创建结构的实例:

fos_leg = FOS_LEG()

error_out需要是一个可写字符串:

error_out = ctypes.create_string_buffer(FOSAPI_MSG_LEN)

然后通过引用结构调用该函数:

mydll._fos_calc_flight(b"04042014",b"0800",b"KOKC",b"KATL",b"H25B",ctypes.byref(fos_leg),error_out,1,b"AP",b"AP")