1. Low-level Windows wrapper
- Posted by jmduro Dec 26, 2015
- 1466 views
I have uploaded on RDS site a low-level windows wrapper based on the way Bernie Ryan built his w32engin: http://rapideuphoria.com/windows2.zip. I could not understand why wrapping could not refer to Windows original types. When moving fom 32-bit to 64-bit, a lot of functions don't work anymore because some types have different sizes. If you lost information about the original types, you are getting lost. So I found a way to always refer to original types to keep this information and allocate memory according to the architecture. This way, the same function should run with 32-bit and 64-bit interpreter without any change. This could not have been done without the help of Andreas Wagner and Matt Lewis' work.
It is not perfect: I was not able to deal correctly with 64-bit callbacks. However, it is a good basis to develop high-level libraries. Many thousands windows functions are wrapped. Windows types keep their original name with minor modifications:
- "unsigned char" becomes "unsigned_char"
- char* becomes pchar
- INT** becomes PPINT
The P prefix for a pointer, PP for pointer of pointer, and so on. When dealing with structures, user can rely on some functions:
- setParams(pointer, input, definition) fills a structure defined by "definition" at position "p" in memory (pointer) with content given by "input"
- getParams(pointer, definition) does the opposite
- getStructureLength(definition) gives the size of a structure
As with w32engin and WinLib, only functions that are really used are loaded into memory (handle != 0).
dirdlg3.exw gives an example of calling.
function dirDlg(sequence title, sequence default="", atom flags=1+16+64) -- BROWSEINFO structure sequence browse_info = {HWND,PCIDLIST_ABSOLUTE,LPTSTR,LPCTSTR,UINT,BFFCALLBACK,LPARAM,int} -- allocate memory according to the architecture (32-bit or 64-bit) integer lg = getStructureLength(browse_info) atom BrowseInfo = allocate(lg) -- fill the structure atom szDispName=allocate(MAX_PATH) for i=0 to MAX_PATH-1 do poke(szDispName+i,0) end for atom sztitle=allocate_string(title) atom startdir=allocate_string(default) setParams(BrowseInfo, {WinHwnd,0,szDispName,sztitle,flags,call_back(routine_id("callbackselect")),startdir,0}, browse_info) -- WinHwnd is a tinEWG global variable which provides main window handle atom pidl=0 sequence ret_dir="" -- call the Windows function pidl = callFunc(xSHBrowseForFolderA, {BrowseInfo}) if pidl then if callFunc(xSHGetPathFromIDListA, {pidl,szDispName}) then ret_dir=peek_string(szDispName) else ret_dir="" end if end if free (sztitle) free (BrowseInfo) free (szDispName) free (startdir) return ret_dir end function
I should have used getParams() to retrieve the function results but I feel tired and I am not able to do the job now.
Unfortunately, this example does not work correctly with 64-bit architecture. It uses callbacks and I didn't find where it goes wrong.
Jean-Marc
2. Re: Low-level Windows wrapper
- Posted by jmduro Dec 26, 2015
- 1442 views
I should have used getParams() to retrieve the function results but I feel tired and I am not able to do the job now.
I just realize that setParams() and getParams() are very badly named. They set and get parameters for structures only, so getParams() cannot be used to retrieve all functions return value.
I will rename setParams() to setStructure() and getParams() to getStructure() to avoid some more misunderstanding.