from cffi import FFI ffibuilder = FFI() import pathlib this_dir = pathlib.Path().absolute() # cdef() expects a single string declaring the C types, functions and # globals needed to use the shared object. It must be in valid C syntax. ffibuilder.cdef(""" typedef struct { FILE* HdrFile_PS; /* File handle for .JHR file */ FILE* TxtFile_PS; /* File handle for .JDT file */ FILE* IdxFile_PS; /* File handle for .JDX file */ FILE* LrdFile_PS; /* File handle for .JLR file */ int Errno_I; /* last i/o error */ int Locked_I; /* is area locked? */ uint32_t LastUserPos_I; /* last position of lastread record */ uint32_t LastUserId_I; /* userid for the last read lastread record */ } s_JamBase; int JAM_OpenMB ( char* Basename_PC, s_JamBase** NewArea_PPS ); int JAM_CloseMB ( s_JamBase* Area_PS ); typedef struct { char Signature[4]; /* followed by */ uint32_t DateCreated; /* Creation date */ uint32_t ModCounter; /* Last processed counter */ uint32_t ActiveMsgs; /* Number of active (not deleted) msgs */ uint32_t PasswordCRC; /* CRC-32 of password to access */ uint32_t BaseMsgNum; /* Lowest message number in index file */ char RSRVD[1000]; /* Reserved space */ } s_JamBaseHeader; typedef struct { char Signature[4]; /* followed by */ uint16_t Revision; /* CURRENTREVLEV */ uint16_t ReservedWord; /* Reserved */ uint32_t SubfieldLen; /* Length of Subfields */ uint32_t TimesRead; /* Number of times message read */ uint32_t MsgIdCRC; /* CRC-32 of MSGID line */ uint32_t ReplyCRC; /* CRC-32 of REPLY line */ uint32_t ReplyTo; /* This msg is a reply to.. */ uint32_t Reply1st; /* First reply to this msg */ uint32_t ReplyNext; /* Next msg in reply chain */ uint32_t DateWritten; /* When msg was written */ uint32_t DateReceived; /* When msg was received/read */ uint32_t DateProcessed; /* When msg was processed by packer */ uint32_t MsgNum; /* Message number (1-based) */ uint32_t Attribute; /* Msg attribute, see "Status bits" */ uint32_t Attribute2; /* Reserved for future use */ uint32_t TxtOffset; /* Offset of text in text file */ uint32_t TxtLen; /* Length of message text */ uint32_t PasswordCRC; /* CRC-32 of password to access msg */ uint32_t Cost; /* Cost of message */ } s_JamMsgHeader; typedef struct { uint16_t LoID; /* Field ID, 0 - 0xffff */ uint16_t HiID; /* Reserved for future use */ uint32_t DatLen; /* Length of buffer that follows */ char* Buffer; /* DatLen bytes of data */ } s_JamSubfield; typedef struct { uint16_t LoID; /* Field ID, 0 - 0xffff */ uint16_t HiID; /* Reserved for future use */ uint32_t DatLen; /* Length of buffer that follows */ } s_JamSaveSubfield; typedef struct { uint32_t UserCRC; /* CRC-32 of destination username */ uint32_t HdrOffset; /* Offset of header in .JHR file */ } s_JamIndex; typedef struct { uint32_t UserCRC; /* CRC-32 of user name (lowercase) */ uint32_t UserID; /* Unique UserID */ uint32_t LastReadMsg; /* Last read message number */ uint32_t HighReadMsg; /* Highest read message number */ } s_JamLastRead; typedef struct { s_JamSubfield** Fields; uint32_t NumFields; uint32_t NumAlloc; } s_JamSubPacket; int JAM_LockMB( s_JamBase* Area_PS, int Timeout_I ); int JAM_UnlockMB( s_JamBase* Area_PS ); int JAM_ReadMBHeader( s_JamBase* Area_PS, s_JamBaseHeader* Header_PS ); int JAM_WriteMBHeader( s_JamBase* Area_PS, s_JamBaseHeader* Header_PS ); int JAM_GetMBSize( s_JamBase* Area_PS, uint32_t* Messages_PI ); int JAM_ReadMsgHeader ( s_JamBase* Area_PS, uint32_t MsgNo_I, s_JamMsgHeader* Header_PS, s_JamSubPacket** SubfieldPack_PPS ); int JAM_ReadMsgText ( s_JamBase* Area_PS, uint32_t Offset_I, uint32_t Length_I, char* Buffer_PC ); int JAM_AddMessage ( s_JamBase* Area_PS, s_JamMsgHeader* Header_PS, s_JamSubPacket* SubPack_PS, char* Text_PC, uint32_t TextLen_I ); int JAM_AddEmptyMessage ( s_JamBase* Area_PS ); int JAM_DeleteMessage ( s_JamBase* Base_PS, uint32_t MsgNo_I ); int JAM_ChangeMsgHeader ( s_JamBase* Area_PS, uint32_t MsgNo_I, s_JamMsgHeader* Header_PS ); int JAM_ClearMsgHeader ( s_JamMsgHeader* Header_PS ); int JAM_Errno ( s_JamBase* Area_PS ); s_JamSubPacket* JAM_NewSubPacket ( void ); int JAM_DelSubPacket ( s_JamSubPacket* SubPack_PS ); s_JamSubfield* JAM_GetSubfield ( s_JamSubPacket* SubPack_PS ); s_JamSubfield* JAM_GetSubfield_R ( s_JamSubPacket* SubPack_PS , uint32_t* Count_PI); int JAM_PutSubfield ( s_JamSubPacket* SubPack_PS, s_JamSubfield* Field_PS ); uint32_t JAM_Crc32 ( char* Buffer_PC, uint32_t Length_I ); void free(void*); """) # int JAM_CloseMB ( s_JamBase* Area_PS ); # # """) # set_source() gives the name of the python extension module to # produce, and some C source code as a string. This C code needs # to make the declarated functions, types and globals available, # so it is often just the "#include". ffibuilder.set_source("_pi_cffi", """ #include "jam.h" // the C header of the library """, # libraries=['jamlib.a'], # library_dirs=[this_dir.as_posix()], # extra_link_args=["-Wl,-rpath,."], extra_link_args=["jamlib.a"], ) # library name, for the linker if __name__ == "__main__": ffibuilder.compile(verbose=True)