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

Python 3.x Python 3.4.3 ctypes:尝试将结构作为输出参数传递给函数失败,python-3.x,ctypes,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

以下是供应商给我的描述功能的内容

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")
下面是返回的错误

回溯(最近一次调用last):文件“test.py”,第28行,在 mydll._fos_calc_航班(“04042014”、“0800”、“KOKC”、“KATL”、“H25B”、fos_航段,er ror_out,1,“AP”,“AP”)ctypes.ArgumentError:参数6::不知道如何转换参数6


非常感谢您未经测试的帮助,但您的结构应该更像:

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
最后,输出参数需要是所需类型的实例<代码>指针仅声明一种类型,因此您希望创建该结构的实例:

fos_leg = FOS_LEG()
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")
error\u out
必须是可写字符串:

error_out = ctypes.create_string_buffer(FOSAPI_MSG_LEN)
然后使用对结构的引用调用函数:

fos_leg = FOS_LEG()
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")

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

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
最后,输出参数需要是所需类型的实例<代码>指针仅声明一种类型,因此您希望创建该结构的实例:

fos_leg = FOS_LEG()
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")
error\u out
必须是可写字符串:

error_out = ctypes.create_string_buffer(FOSAPI_MSG_LEN)
然后使用对结构的引用调用函数:

fos_leg = FOS_LEG()
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")

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

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
最后,输出参数需要是所需类型的实例<代码>指针仅声明一种类型,因此您希望创建该结构的实例:

fos_leg = FOS_LEG()
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")
error\u out
必须是可写字符串:

error_out = ctypes.create_string_buffer(FOSAPI_MSG_LEN)
然后使用对结构的引用调用函数:

fos_leg = FOS_LEG()
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")

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

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
最后,输出参数需要是所需类型的实例<代码>指针仅声明一种类型,因此您希望创建该结构的实例:

fos_leg = FOS_LEG()
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")
error\u out
必须是可写字符串:

error_out = ctypes.create_string_buffer(FOSAPI_MSG_LEN)
然后使用对结构的引用调用函数:

fos_leg = FOS_LEG()
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")


您需要传递为类分配的空间。您只传递一个指向该类的指针。试试看:
fos=fos_LEG()
和pass
ctypes.addressof(fos)
您需要传递为类分配的空间。您只传递一个指向该类的指针。试试看:
fos=fos_LEG()
和pass
ctypes.addressof(fos)
您需要传递为类分配的空间。您只传递一个指向该类的指针。试试看:
fos=fos_LEG()
和pass
ctypes.addressof(fos)
您需要传递为类分配的空间。您只传递一个指向该类的指针。试试看:
fos=fos_LEG()
和pass
ctypes.addressof(fos)
谢谢标记,现在它抱怨当我在结构中使用FOSAPI_MSG_LEN时没有定义它。“我需要事先申报吗?”阿达姆文尼达,当然。您没有在C代码中提供定义,但是从您在代码中的注释可以使用
FOSAPI_MSG_LEN=256
@Mark-明白了,谢谢-我现在得到的是mydll。_fos_calc_flight.argtypes=[C_char_p,C_char_p,C_char_p,C_char_p,C_char_,C_char,C_char,C_char,C_名称错误:名称“c_char_p”不正确defined@AdamvonNieda,它在
ctypes
模块中定义。在前面加上
ctypes.c\u char\u p
从ctypes导入c\u char\u p
。我更新了代码,但正如我所说,这是未经测试的,只是指出了差距。好的,明白了。请容忍我,现在它告诉我论点1是错误的类型。我们将其定义为“ctypes.c_char_p”以匹配函数“char”,并将其传递给“04042014”。我不明白为什么它会给出那个错误?谢谢Mark,它现在抱怨说当我在结构中使用FOSAPI_MSG_LEN时,它没有定义它。“我需要事先申报吗?”阿达姆文尼达,当然。您没有在C代码中提供定义,但是从您在代码中的注释可以使用
FOSAPI_MSG_LEN=256
@Mark-明白了,谢谢-我现在得到的是mydll。_fos_calc_flight.argtypes=[C_char_p,C_char_p,C_char_p,C_char_p,C_char_,C_char,C_char,C_char,C_名称错误:名称“c_char_p”不正确defined@AdamvonNieda,它在
ctypes
模块中定义。在前面加上
ctypes.c\u char\u p
从ctypes导入c\u char\u p
。我更新了代码,但正如我所说,这是未经测试的,只是指出了差距。好的,明白了。请容忍我,现在它告诉我论点1是错误的类型。我们将其定义为“ctypes.c_char_p”以匹配函数“char”,并将其传递给“04042014”。我不明白为什么它会给出那个错误?谢谢Mark,它现在抱怨说当我在结构中使用FOSAPI_MSG_LEN时,它没有定义它。“我需要事先申报吗?”阿达姆文尼达,当然。您没有在C代码中提供定义,但是从您在代码中的注释可以使用
FOSAPI_MSG_LEN=256
@Mark-明白了,谢谢-我现在得到的是mydll。_fos_calc_flight.argtypes=[C_char_p,C_char_p,C_char_p,C_char_p,C_char_,C_char,C_char,C_char,C_名称错误:名称“c_char_p”不正确defined@AdamvonNieda,它在
ctypes
模块中定义。在前面加上
ctypes.c\u char\u p
从ctypes导入c\u char\u p
。我更新了代码,但正如我所说,这是未经测试的,只是指出了差距。好的,明白了。请容忍我,现在它告诉我论点1是错误的类型。我们将其定义为“ctypes.c_char_p”,以匹配函数“char”和pa