1. cffi.e
- Posted by AlexXX Feb 17, 2021
- 1383 views
I try to apply cffi. e, it seems I do everything as in the documentation examples, an error occurs: F:\phix\builtins\cffi.e:232 in procedure err() attempt to divide by 0 msg = `unknown size typedef` ... called from F:\phix\builtins\cffi.e:455 in function do_type() mtype = `typedef` machine = 32' ' substruct = 0
by the way, in the example about get_struct_size error: integer size = get_struct_field(id MBP).
And I still don't understand
integer rid = define_c_func(object lib, object fname, sequence args, atom return_type)
integer rid = define_cffi_func(object lib, string cdef, integer machine=machine_bits ())
and where is the function name passed
include cffi.e constant SM_SYSTRAY = WM_USER + 5 constant tNOTIFYICONDATA=""" typedef struct _NOTIFYICONDATA { DWORD cbSize; HWND hWnd; UINT uID; UINT uFlags; UINT uCallbackMessage; HICON hIcon; TCHAR szTip[128]; } NOTIFYICONDATA, *PNOTIFYICONDATA; """ set_unicode(0) constant integer idNOTIFYICONDATA = define_struct(tNOTIFYICONDATA) atom pNOTIFYICONDATA = allocate_struct(idNOTIFYICONDATA) constant SHELL32 = open_dll("shell32") -- -- constant Shell_NotifyIconA = define_cffi_func(SHELL32,tNOTIFYICONDATA) -- -- dwMessage constant NIM_ADD = 0, NIM_MODIFY = 1, NIM_DELETE = 2, NIF_MESSAGE = 1, NIF_ICON = 2, NIF_TIP = 4 -- procedure init_pNOTIFYICONDATA(atom hwnd, atom id, object flags, atom icon, object tip) integer size = get_struct_size(idNOTIFYICONDATA) set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"cbSize",size) set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"uFlags",flags) set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"uCallbackMessage",SM_SYSTRAY) end procedure
2. Re: cffi.e
- Posted by petelomax Feb 17, 2021
- 1379 views
The structure and function need different definitions. You need something like this:
constant tShell_NotifyIconA = """ BOOL Shell_NotifyIcon( _In_ DWORD dwMessage, _In_ PNOTIFYICONDATA lpdata ); """ -- --constant Shell_NotifyIconA = define_cffi_func(SHELL32,tNOTIFYICONDATA) constant Shell_NotifyIconA = define_cffi_func(SHELL32,tShell_NotifyIconA)
3. Re: cffi.e
- Posted by AlexXX Feb 18, 2021
- 1339 views
Thanks. Could you tell me how to determine the size of the c-struct in the documentation?
4. Re: cffi.e
- Posted by petelomax Feb 18, 2021
- 1338 views
Thanks. Could you tell me how to determine the size of the c-struct in the documentation?
erm, get_struct_size(idNOTIFYICONDATA)? I don't understand how you couldn't find that.
You only tend to need that if there are (packed) arrays of them, or (like the pieces of BITMAPINFOHEADER) they're optionally all mashed up together, or otherwise contiguous in memory.
5. Re: cffi.e
- Posted by AlexXX Feb 19, 2021
- 1304 views
I was confused by what the documentation says: Get the total size of a structure previously defined by define_struct().
6. Re: cffi.e
- Posted by AlexXX Feb 19, 2021
- 1319 views
Again I made a mistake somewhere:
include cffi.e constant SM_SYSTRAY = 0x0400 + 5 constant tLoadImageA=""" HANDLE LoadImageA( HINSTANCE hInst, LPCSTR name, UINT type, int cx, int cy, UINT fuLoad ); """ constant SHELL32 = open_dll("shell32") constant LoadImageA=define_cffi_func(SHELL32,tLoadImageA) constant tShell_NotifyIconA = """ BOOL Shell_NotifyIcon( DWORD dwMessage, NOTIFYICONDATA* lpData ); """ constant NIM_ADD = 0, NIM_MODIFY = 1, NIM_DELETE = 2, NIF_MESSAGE = 1, NIF_ICON = 2, NIF_TIP = 4 constant Shell_NotifyIconA = define_cffi_func(SHELL32,tShell_NotifyIconA) struct t_N """ typedef struct _NOTIFYICONDATAA { DWORD cbSize; HWND hWnd; UINT uID; UINT uFlags; UINT uCallbackMessage; HICON hIcon; CHAR szTip[128]; DWORD dwState; DWORD dwStateMask; CHAR szInfo[256]; union { UINT uTimeout; UINT uVersion; } DUMMYUNIONNAME; CHAR szInfoTitle[64]; DWORD dwInfoFlags; GUID guidItem; HICON hBalloonIcon; } NOTIFYICONDATAA, *PNOTIFYICONDATAA; """ end struct
f:\phix\builtins\cffi.e:232 in procedure err() attempt to divide by 0 msg = `unknown size GUID` ... called from f:\phix\builtins\cffi.e:455 in function do_type() mtype = `GUID` machine = 32' ' substruct = 0 k = 0 size = <novalue> align = <novalue> signed = 1 mname = `guidItem`It is not clear in which line of my program the error is.
7. Re: cffi.e
- Posted by petelomax Feb 19, 2021
- 1309 views
Again I made a mistake somewhere:
First, it is looking in the wrong lib:
--constant LoadImageA=define_cffi_func(SHELL32,tLoadImageA) constant USER32 = open_dll("user32") constant LoadImageA=define_cffi_func(USER32,tLoadImageA)
Second, it needs something like this (alternatively a plain define_struct would do), before struct t_N:
struct t_GUID """ typedef struct _GUID { DWORD Data1; WORD Data2; WORD Data3; BYTE Data4[8]; } GUID; """ end struct
It is not clear in which line of my program the error is.
Fair point. I've improved the error handling in a few places for the next release.
(I might be able to put a source patch together but it's a bit all over the place.)
For now, you'll need to look a bit further down in the ex.err for whatever called cffi.e/structs.e/etc - but that won't really help for compile-time errors.
8. Re: cffi.e
- Posted by petelomax Feb 19, 2021
- 1296 views
I was confused by what the documentation says: Get the total size of a structure previously defined by define_struct().
That just refers to getting the size being a three-step process:
constant t_NOTIFYICONDATA = "..." constant id_NOTIFYICONDATA = define_struct(t_NOTIFYICONDATA) integer size = get_struct_size(id_NOTIFYICONDATA)
9. Re: cffi.e
- Posted by AlexXX Feb 20, 2021
- 1249 views
I made a working layout, the icon is displayed, but when you hover the mouse disappears. I didn't understand c-struct, if you can show a working example, I didn't find anything in the demo
include cffi.e include ..\demo\arwen\arwen.ew constant SM_SYSTRAY = #400 + 5 with trace --trace(1) constant tLoadImageA = """ HANDLE LoadImageA( HINSTANCE hInst, LPCSTR name, UINT type, int cx, int cy, UINT fuLoad ); """ set_unicode(0) constant SHELL32 = open_dll("shell32") constant USER32 = open_dll("user32") constant LoadImageA = define_cffi_func(USER32,tLoadImageA) atom lpszName=allocate_string("test.ico") constant icon_t=c_func(LoadImageA,{0,lpszName,1,0,0,0x00000010}) ? icon_t constant tShell_NotifyIconA = """ BOOL Shell_NotifyIcon( DWORD dwMessage, NOTIFYICONDATA* lpData ); """ constant NIM_ADD = 0, NIM_MODIFY = 1, NIM_DELETE = 2, NIF_MESSAGE = 1, NIF_ICON = 2, NIF_TIP = 4 constant Shell_NotifyIconA = define_cffi_func(SHELL32,tShell_NotifyIconA) constant tNOTIFYICONDATA=""" typedef struct _NOTIFYICONDATA { DWORD cbSize; HWND hWnd; UINT uID; UINT uFlags; UINT uCallbackMessage; HICON hIcon; TCHAR szTip[128]; } NOTIFYICONDATA, *PNOTIFYICONDATA; """ constant integer idNOTIFYICONDATA = define_struct(tNOTIFYICONDATA) atom pNOTIFYICONDATA = allocate_struct(idNOTIFYICONDATA) --/* struct t_NOTIFYICONDATAA """ typedef struct _NOTIFYICONDATAA { DWORD cbSize; HWND hWnd; UINT uID; UINT uFlags; UINT uCallbackMessage; HICON hIcon; CHAR szTip[128]; DWORD dwState; DWORD dwStateMask; CHAR szInfo[256]; CHAR szInfoTitle[64]; DWORD dwInfoFlags; GUID guidItem; HICON hBalloonIcon; } NOTIFYICONDATAA, *PNOTIFYICONDATAA; """ end struct --*/ ------------------------------------------------------------------------- constant MainWin = create(Window, "Example 02", 0, NULL, 25, 25, 300, 200, 0) object flags={NIF_MESSAGE,NIF_ICON,NIF_TIP} integer size = get_struct_size(idNOTIFYICONDATA) set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"cbSize",size) flags = or_all(flags) atom pStr=allocate_string("My icon") set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"hWnd",MainWin) set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"uFlags",flags) set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"uCallbackMessage",SM_SYSTRAY) set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"szTip",pStr) set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"hIcon",icon_t) atom a=c_func(Shell_NotifyIconA,{NIM_ADD,pNOTIFYICONDATA}) ? a function MainHandler(integer id, integer msg, atom wParam, object lParam) if msg = SM_SYSTRAY then ? "fsdfsafsfa" end if return 0 end function setHandler(MainWin,routine_id("MainHandler")) WinMain(MainWin, SW_NORMAL) free(pNOTIFYICONDATA) free (pStr) free(lpszName)
10. Re: cffi.e
- Posted by AlexXX Feb 20, 2021
- 1247 views
I tried to compile this program, it turned out ~ 1 MB, why so much?
11. Re: cffi.e
- Posted by petelomax Feb 20, 2021
- 1333 views
I tried to compile this program, it turned out ~ 1 MB, why so much?
If you run p -d test it will create a (big) list.asm showing a full assembly listing (except for anything marked "without debug").
If you modify and run either demo\pGUI\filedump.exw (change the load_file() around line 10100) or demo\arwendemo\filedumpN.exw (change the load_file() circa line 9588) and it will show every single byte in the file, and F9 will show a simple graphical memory/file layout.
The bulk of that 1MB is the runtime, error reporting, and a full symbol table to facilitate the latter.
I didn't understand c-struct, if you can show a working example, I didn't find anything in the demo
There are not very many, demo\winwire.exw probably being the most complete example.
You are obviously doing something right to get as far as you have.
I made a working layout, the icon is displayed, but when you hover the mouse disappears.
Sorry, that's all a bit beyond my ken.
This sort of shell programming, asking something else to do stuff for you (and having it fail silently when you miss one out of 83 things), is not my forte.
Is there an original source that you are translating from?
I think this may be a candidate for posting on StackOverflow: * we want a few questions on SO [and the like] anyway, to get Eu/Phix noticed. * the question should be composed here in full on this forum first. * can anyone else offer their time to assist here (overcome any language barriers etc)?
12. Re: cffi.e
- Posted by AlexXX Feb 20, 2021
- 1278 views
There was no one original source code. This is a reading of the MSDN and a library: System Tray Icon
--23/June/2001
--Thomas Parslow (PatRat)
--patrat@rat-software.com
-- updated 07/April/2003
-- by Greg Haberek (g.haberek@comcast.net)
-- now supports setHandler()
with an attempt to use the capabilities of Phix.
I found that this behavior happens if the hWnd field is not filled in
13. Re: cffi.e
- Posted by petelomax Feb 20, 2021
- 1260 views
I found that this behavior happens if the hWnd field is not filled in
Did you manage to solve it then? Presumably as follows (works for me)
-- set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"hWnd",MainWin) set_struct_field(idNOTIFYICONDATA,pNOTIFYICONDATA,"hWnd",getHwnd(MainWin))
14. Re: cffi.e
- Posted by AlexXX Feb 20, 2021
- 1258 views
I went through all the Phix documentation looking for a similar function :((Where, where I can read about all the functions of the language). Yes, now everything works and I will bring the code to a normal form. Thank you so much, it was a learning experience.
15. Re: cffi.e
- Posted by AlexXX Feb 24, 2021
- 1200 views
I was happy early, the field TCHAR szTip[128] is not displayed normally, in C this command is used:
lstrcpyn(nid.szTip, _T("Tool tip for my icon"), sizeof(nid.szTip)/sizeof(nid.szTip[0]);
but how to do this in Phix I can not figure out
16. Re: cffi.e
- Posted by petelomax Feb 24, 2021
- 1152 views
- Last edited Feb 25, 2021
Oh my, you're not wrong, there was no mechanism to do that at all. Here's a replacement routine for cffi.e, line 1046
global procedure set_struct_field(integer id, atom pStruct, atom_string field, atom_string v) sequence {membernames,details} = get_smembers(id) integer k = iff(string(field)?find(field,membernames):field) integer {?,size,offset} = details[k] if atom(v) then pokeN(pStruct+offset,v,size) else poke(pStruct+offset,v) end if end procedure
And likewise there was no way to retrieve, here's a new routine for that, add it just after get_struct_field():
global function get_struct_string(integer id, atom pStruct, string field, integer len) sequence {membernames,details} = get_smembers(id) integer k = find(field,membernames) integer {?,?,offset} = details[k] return peek({pStruct+offset,len}) end function
Note that it is your responsibility to pass short-enough strings to set_struct_field(), and the right length to get_struct_string(), since cffi.e cannot check any of that for you, and likewise add/trim trailing zeroes (or '\0') where needed.
Also note the above are ansi-only, I will add the required widestring handling in a bit, before I move on [if you're not calling set_unicode() the next version will likely crash].
I will also update the docs - I should also note that struct x """...""" end struct use of cffi.e won't play nice with any embedded TCHAR[nnn] and similar fields, should you by any chance happen to be considering that.
17. Re: cffi.e
- Posted by AlexXX Feb 25, 2021
- 1163 views
Thank you very much, everything works. By the way, you can also mention in the documentation that you should not put comments in the definition of type and functions (well, I'm not the only one who can do this)
18. Re: cffi.e
- Posted by petelomax Feb 25, 2021
- 1154 views
Thank you very much, everything works. By the way, you can also mention in the documentation that you should not put comments in the definition of type and functions (well, I'm not the only one who can do this)
Actually you can put comments in but they must be C-style, ie/eg // comment, or /* comment */, not -- comment. Will mention.