cffi
- Posted by petelomax Aug 31, 2015
- 2295 views
I've written a simple cffi implementation.
The intro reads:
-- -- cffi.e -- ====== -- -- Eliminates most of the byte-counting needed when interfacing to C routines. -- The motivation behind this was that while I had many of the windows API -- structures laboriously translated to offsets for 32-bit from many years -- ago, they would all have otherwise needed re-doing for 64-bit. -- -- I must stress that any savings are limited to converting C header (.h) files, -- or more accurately fragments copied verbatim from said, which would otherwise -- have to be done line-by-line manually. There is no new fancy slick syntax to -- help with the code that follows, or anything remotely like that. Although it -- knows the names, offsets and sizes of fields, that does not mean that you no -- longer have to fill them in! But there is less chance of being out-by-2 or -- whetever on the 4th field and therefore all the rest. -- -- Structures: -- =========== -- id = define_struct(s) parses C struct definitions into sizes/offsets etc. -- pStruct = allocate_struct(id) -- (invoke free(pStruct) when done) -- set_struct_field(id,pStruct,"name",value) -- value = get_struct_field(id,pStruct,"name") -- {offset,size,sign} = get_field_details(id,"name") -- size = get_struct_size(id) -- -- Routine definition: -- =================== -- integer rid = define_cfunc(object lib, string cdef) -- integer rid = define_cproc(object lib, string cdef)The full source can be grabbed from http://phix.is-great.org/cffi.e
A little test, works on Phix and OE 4.1.0.
include builtins\cffi.e constant tMB=""" int WINAPI MessageBox( _In_opt_ HWND hWnd, _In_opt_ LPCTSTR lpText, _In_opt_ LPCTSTR lpCaption, _In_ UINT uType ); """ set_unicode(0) constant xMessageBox = define_cfunc("user32.dll",tMB,0) --?c_func(xMessageBox,{0,"text","caption",0}) atom pText = allocate_string("text"), pCaption = allocate_string("caption") if 01 then ?c_func(xMessageBox,{0,pText,pCaption,0}) end if constant tMBP=""" typedef struct { UINT cbSize; HWND hwndOwner; HINSTANCE hInstance; LPCTSTR lpszText; LPCTSTR lpszCaption; DWORD dwStyle; LPCTSTR lpszIcon; DWORD_PTR dwContextHelpId; MSGBOXCALLBACK lpfnMsgBoxCallback; DWORD dwLanguageId; } MSGBOXPARAMS, *PMSGBOXPARAMS; """ constant tMBI = """ int WINAPI MessageBoxIndirect( _In_ const LPMSGBOXPARAMS lpMsgBoxParams ); """ integer idMBP = define_struct(tMBP) integer xMBI = define_cfunc("user32.dll",tMBI) atom pMBP = allocate_struct(idMBP) set_struct_field(idMBP,pMBP,"cbSize",get_struct_size(idMBP)) set_struct_field(idMBP,pMBP,"lpszText",pText) set_struct_field(idMBP,pMBP,"lpszCaption",pCaption) ?c_func(xMBI,{pMBP})
Just in case you need it you can get the current version of pcolumn.e from http://openeuphoria.org/pastey/274.wc
I even got a version to work on RDS Eu 2.4, but it turned out a bit grubby.
I am thinking that things like MAX_PATH are probably best handled manually, unless someone has a better idea.
Let me know what you think,
Pete
PS The triple-quoted constants do not seem to be working.