luaffi/luaffi question: Calling c function ptr possible?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

luaffi/luaffi question: Calling c function ptr possible?

Björn Kalkbrenner
Hi,

i have a question regarding the use of luaffi
(https://github.com/jmckaskill/luaffi) and since i have read this
mailinglist silently the last months the answers given to questions were
really quite helpful, it's a great list - thanks to the contributors.

Maybe someone is here using luaffi or luajit/ffi (if the differences to
luajit isn't that big) who can give me a direction. The OS is Windows.

I am creating a library which is dynamically loaded by another host
process. I have no control over the host process and the API is fixed.

This host process calls functions in my library receiving a function
pointer as argument (to return results async) and some struct memory
adresses. My function adds these values to the lua stack and executes a
lua script with lua_pcall. In other words, i am mapping calls to the
library directly to lua-functions in my script.

Currently i am using luaffi in my script calling win32 API functions and
working with the structs which is working great, the last thing which i
have not yet resolved is calling the given callback which i have
received as function pointer.

Can i cast a function pointer to something luaffi interprets as callable
function?

I have tried this (snipped out of the code):
======================================================================


ffi.cdef[[
     typedef void (__stdcall *RESULT_CB)(DWORD ResultID,LONG Result);
]]

function libraryFunctionXYZ(data)
   local _cb = =ffi.cast("RESULT_CB*",data.cbAddr)
   _cb(0,0);
end

=====================================================================

That doesn't work, i am getting the error:

"only function callbacks are callable"


Is it even possible to cast a function pointer memory address to
something luaffi can understand/call?


Bye
Björn

Reply | Threaded
Open this post in threaded view
|

Re: luaffi/luaffi question: Calling c function ptr possible?

Björn Kalkbrenner
Hi,

 > Is it even possible to cast a function pointer memory address to
 > something luaffi can understand/call?

i think i have solved the problem, it seems to work. The cast was wrong.


=====
local cbAddr = ffi.cast("RESULT_CB*",data.cbAddr);
local _cb = ffi.cast("RESULT_CB",cbAddr[0]);
_cb(data.ResultID,0);
=====

Bye
Björn


Reply | Threaded
Open this post in threaded view
|

Re: luaffi/luaffi question: Calling c function ptr possible?

Tom N Harris-2
In reply to this post by Björn Kalkbrenner
On Friday, July 10, 2015 10:32:55 AM Björn Kalkbrenner wrote:

> Hi,
>
> i have a question regarding the use of luaffi
> (https://github.com/jmckaskill/luaffi) and since i have read this
> mailinglist silently the last months the answers given to questions were
> really quite helpful, it's a great list - thanks to the contributors.
>
> Maybe someone is here using luaffi or luajit/ffi (if the differences to
> luajit isn't that big) who can give me a direction. The OS is Windows.
>
> I am creating a library which is dynamically loaded by another host
> process. I have no control over the host process and the API is fixed.
>
> This host process calls functions in my library receiving a function
> pointer as argument (to return results async) and some struct memory
> adresses. My function adds these values to the lua stack and executes a
> lua script with lua_pcall. In other words, i am mapping calls to the
> library directly to lua-functions in my script.
>
> Currently i am using luaffi in my script calling win32 API functions and
> working with the structs which is working great, the last thing which i
> have not yet resolved is calling the given callback which i have
> received as function pointer.
>

Using FFI here seems like driving a finishing nail with a sledgehammer. Were
you aware of the native winapi[1] bindings?

For the callback, the function pointer can be pushed to Lua as lightuserdata.
Then define your own C function to be called from Lua

int mycallback(Lua_state *L) {
    RESULT_CB cb = lua_touserdata(L, 1);
    cb(lua_tointeger(L, 2), 0);
    return 0;
}

FFI isn't just an extra dependency for you to carry, it's also very, very slow
unless you're using LuaJIT.

[1] https://stevedonovan.github.io/winapi/topics/readme.md.html

--
tom <[hidden email]>

Reply | Threaded
Open this post in threaded view
|

Re: luaffi/luaffi question: Calling c function ptr possible?

Coda Highland
On Fri, Jul 10, 2015 at 10:07 AM, Tom N Harris <[hidden email]> wrote:
> FFI isn't just an extra dependency for you to carry, it's also very, very slow
> unless you're using LuaJIT.

And if you ARE using LuaJIT, the bindings drag down the performance of
the whole routine.

When it comes to optimization, it's often best to not consider the two
platforms as equal.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: luaffi/luaffi question: Calling c function ptr possible?

Javier Guerra Giraldez
In reply to this post by Tom N Harris-2
On Fri, Jul 10, 2015 at 12:07 PM, Tom N Harris <[hidden email]> wrote:
> FFI isn't just an extra dependency for you to carry, it's also very, very slow
> unless you're using LuaJIT.


a very rough speed ranking of Lua->C interfacing methods, from fastest
to slowest:

1.- LuaJIT, fully compiled FFI
2.- LuaJIT, Lua C API
3.- PUC Lua, Lua C API
4.- LuaJIT, intepreted FFI
5.- any Lua, luaffi module

notes:

- even better than 1: don't use C.  it's faster to do tight loops in
fully compiled Lua code than to call C code for small things.

- big (several orders of magnitude) difference from 1 to 2

- 2 and 3 are roughly similar.  an interesting data point is the Redis
server. It can use LuaJIT, but there's very small performance
advantage (the author cites around 10%)

- very perceptible difference from 3 to 4 (that's why under LuaJIT you
shouldn't use the FFI in tight loops if you're not sure this inner
code is compiled)

- i haven't personally benchmarked the luaffi module (case 5), but
it's a pretty heavy wrapping on top of the Lua C API, so it's
noticeably slower than 3.  the 4 case does much of the same, but in
the core of the LuaJIT interpreter (which is quite fast, in fact)
instead of the C API, so it has a significant advantage over 5.  my
feeling is that the difference from 4 to 5 is similar to the one from
3 to 4.

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: luaffi/luaffi question: Calling c function ptr possible?

Björn Kalkbrenner
In reply to this post by Tom N Harris-2
On 10.07.2015 19:07, Tom N Harris wrote:

> Using FFI here seems like driving a finishing nail with a sledgehammer. Were
> you aware of the native winapi[1] bindings?

Yes  but they are very specific. I can't just map windows dll's and
functions "dynamically".

> FFI isn't just an extra dependency for you to carry, it's also very, very slow
> unless you're using LuaJIT.

This is just a point of view. Considering my requirement (not my choice)
i can rewrite the sentence:

"When using FFI it's the only dependency i have to carry, even if's very
slow."

Sometimes speed is not a problem if slow things are used wisely. One the
requirement are: only recompile "the core" if it's mandatory.
Lua with LuaFFI seems to solve all of the requirements.

Anyway, thank you for the information about winapi and the example for
the lightuserdata! I will think about that :)

Bye
Björn