I have been discussing improvements to "libcall" with Bram, and Iwould like to get feedback from you.My specific issue is I want to interface with SQLite directly. Iwrote some new functions in my personal version of vim, but they arenot general enough to satisfy Bram, and he's right in this case :)
Basically, this is what is desired:1. The ability to demand-load an arbitrary function from an arbitraryDLL/SO, and deal with the parameters in an easy way.2. The ability to write a 'callback' function in vimscript, alsodealing with parameters etc. in a reasonable way.The 'callback' functionality is necessary for interfacing with lots ofDLLs - SQLite, expat and many others. Of course it is possible towrite a wrapper dll and use the existing 'libcall' interface -- and infact, I was doing that for years -- but the existing libcall loads andunloads the DLL every time it's called, making stateful usage verydifficult.I propose a demand-loading mechanism like:call libfunc('dll_function', 'dll_name', "isi",'VimNameForFunction')
(anyone have a better syntax in mind?)So when 'VimNameForFunction' is called, it expects three paramters(isi) to be passed to it, an integer a string and another integer. Itwill then call the 'dll_function' in 'dll_name' (loading dll_name ifit is not already loaded). I use something similar in my Reva Forth.This way, the dll is not loaded unless it is needed, and the bindingtakes place dynamically. When vim quits, the libraries loaded wouldbe unloaded.Parameter conversion should be done behind the scenes, and vim canwarn of improper parameter types or missing parameters.
Likewise, a 'callback' might be declared like:callback MyCallback ( "ssi" )let a = callback_param(0)...endcallbackI think the syntax is reasonable - what do you think?
Bigger question in my mind is how to implement callbacks in vim-script. In Reva it's not a huge problem, as it generates nativecode. But vimscript is completely interpreted, so I am guessing weneed to have a way to have a "thunk" which is passed to the C code inthe DLL, but which when called knows where to vector to.
It may be reasonable to have a limited number of callbacks available,though that would be an unfortunate restriction. Any ideas on this?Oh, one last thing. in the callback example mentioned above, typing"MyCallback" should provide the address of the callback to be passedto calling code. Vim code should never call a 'callback' directly, ofcourse.
function! OpenLib(libname)
" return result of LoadLibrary() in kernel32.dll
return libcall("libcalllib.dll", "OpenLib", a:libname)
endfunction
function! CloseLib(handle)
" call FreeLibrary()
call libcall("libcalllib.dll", "CloseLib", a:handle)
endfunction
function! CallLib(handle, funcname, callargs)
" parse arguments (ex: json library?)
" get address of function by GetProcAddress
" call function.
return libcall("libcalllib.dll", "CallLib", a:handle . "," .
a:funcname . "," + string(a:callargs))
endfunction
--
- Yasuhiro Matsumoto