ctypesسنطور فى هذه الجزئية extension لlibmagic -وهى مكتبة نستطيع من خلالها تحديد نوع الملف من خلال الرقم السحرى magic number- لنستطيع استخدامها فى بايثون عن طريق ال foreign Function library او ال FFL للإختصار والمسماه ب ctypes وهى تقدم انواع بيانات متوافقة مع تلك الموجودة فى ال C وتسمح لنا بإستدعاء الدوال بالمكتبات لنستطيع استغلالها كمانريد (فى الغالب ستريد تقديم wrapper حول مكتبة ما لتستطيع استخدامها بسهولة فى بايثون)
1- قم بتستب libmagic وملفات التطوير libmagic-dev
2- افتح الملف الرأسى magic.h
ستجده يشمل الثوابت المعرفة والدوال المكشوفة والهياكل structures
#ifndef _MAGIC_H
#define _MAGIC_H
#include <sys/types.h>
#define MAGIC_NONE 0x000000 /* No flags */
#define MAGIC_DEBUG 0x000001 /* Turn on debugging */
#define MAGIC_SYMLINK 0x000002 /* Follow symlinks */
#define MAGIC_COMPRESS 0x000004 /* Check inside compressed files */
#define MAGIC_DEVICES 0x000008 /* Look at the contents of devices */
#define MAGIC_MIME_TYPE 0x000010 /* Return only the MIME type */
…..........
#define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */
typedef struct magic_set *magic_t;
magic_t magic_open(int);
void magic_close(magic_t);
…......
const char *magic_file(magic_t, const char *);
const char *magic_descriptor(magic_t, int);
const char *magic_buffer(magic_t, const void *, size_t);
3- نستدعى ال FFL لساحة العمل
from ctypes import *
4- نقوم بتعريف الثوابت
MAGIC_NONE=0x000000 # No flags
MAGIC_DEBUG=0x000001 # Turn on debugging
MAGIC_SYMLINK=0x000002 # Follow symlinks
MAGIC_COMPRESS=0x000004 # Check inside compressed files
MAGIC_DEVICES=0x000008 # Look at the contents of devices
MAGIC_MIME_TYPE=0x000010 # Return only the MIME type
MAGIC_CONTINUE=0x000020 # Return all matches
MAGIC_MIME_ENCODING=0x000400 # Return only the MIME encoding
…
# Defined for backwards compatibility; do nothing
MAGIC_NO_CHECK_FORTRAN=0x000000 # Don't check ascii/fortran
MAGIC_NO_CHECK_TROFF=0x000000 # Don't check ascii/troff
نقوم بتحميل المكتبة -loading-
libmagic=CDLL("libmagic.so") #or even better, check ctypes.util
سريعا حول انواع البيانات (من
http://docs.python.org/library/ctypes.html وراجعها للمزيد)
c_char = Char
c_wchar=wchar_t
c_byte=Char
c_ubyte=Unsigned char
c_short=Short
c_ushort=Unsigned short
c_int=Int
c_uint=Unsigned int
c_long=long
c_ulong=Unsigned long
c_longlong=Long long
c_ulonglong=Unsigned long long
c_float=Float
c_double=Double
c_longdouble=Long double
c_char_p=Char* (null terminated)
c_wchar_p=wchar_t* (null terminated)
c_void_p=Void*
5- نحدد الtypes
magic_t=c_void_p #void pointer.
6- نحدد الدوال
لتحديد دالة بنحدد (القيمة العائدة ال return ) والمعاملات
مثلا الدالة magic_open بتدي عائد من النوع magic_t وبتاخد معامل int
magic_t magic_open(int);
magic_open=libmagic.magic_open
magic_open.restype=magic_t
تحديد القيمة العائدة
magic_open.argtypes=[c_int]
تحديد المعاملات
الدالة magic_file بتدى ريترن بمؤشر ل char وبتاخد معاملات magic_t و مؤشر ل char
const char *magic_file(magic_t, const char *);
magic_file=libmagic.magic_file
magic_file.restype=c_char_
magic_file.argtypes=[magic_t, c_char_p]
بعد انهاء اعلام بايثون عن الدوال اللى محتاجينها نقوم بتقديم الدوال البايثونية السلسة فى الإستخدام
def guess(filepath, flags):
mc=magic_open(flags)
magic_load(mc, None)
res=magic_file(mc, filepath)
magic_close(mc)
return res
المشروع كامل تجده على
http://bitbucket.org/xmonader/libmagicbindings/بإسم pymagic وتجد فيها ايضا مكتبات اضافية لسى شارب وباسكال لإستخدام libmagic
لمثال اكبر ومتعمق فى ctypes تقدر تطلع على binding لمكتبة PCRE على
http://bitbucket.org/xmonader/pypcre/