diff options
Diffstat (limited to 'doc/ext_ffi_semantics.html')
| -rw-r--r-- | doc/ext_ffi_semantics.html | 128 |
1 files changed, 125 insertions, 3 deletions
diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html index 79f25510..7e140e27 100644 --- a/doc/ext_ffi_semantics.html +++ b/doc/ext_ffi_semantics.html | |||
| @@ -297,10 +297,12 @@ arguments to C calls: | |||
| 297 | <tr class="even"> | 297 | <tr class="even"> |
| 298 | <td class="convin">string</td><td class="convop">string data →</td><td class="convout"><tt>const char[]</tt></td></tr> | 298 | <td class="convin">string</td><td class="convop">string data →</td><td class="convout"><tt>const char[]</tt></td></tr> |
| 299 | <tr class="odd separate"> | 299 | <tr class="odd separate"> |
| 300 | <td class="convin">function</td><td class="convop"><a href="#callback">create callback</a> →</td><td class="convout">C function type</td></tr> | ||
| 301 | <tr class="even separate"> | ||
| 300 | <td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout">Array</td></tr> | 302 | <td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout">Array</td></tr> |
| 301 | <tr class="even"> | 303 | <tr class="odd"> |
| 302 | <td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr> | 304 | <td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr> |
| 303 | <tr class="odd separate"> | 305 | <tr class="even separate"> |
| 304 | <td class="convin">cdata</td><td class="convop">cdata payload →</td><td class="convout">C type</td></tr> | 306 | <td class="convin">cdata</td><td class="convop">cdata payload →</td><td class="convout">C type</td></tr> |
| 305 | </table> | 307 | </table> |
| 306 | <p> | 308 | <p> |
| @@ -821,6 +823,127 @@ cdata objects are indistinguishable from pointers returned by C | |||
| 821 | functions (which is one of the reasons why the GC cannot follow them). | 823 | functions (which is one of the reasons why the GC cannot follow them). |
| 822 | </p> | 824 | </p> |
| 823 | 825 | ||
| 826 | <h2 id="callback">Callbacks</h2> | ||
| 827 | <p> | ||
| 828 | The LuaJIT FFI automatically generates special callback functions | ||
| 829 | whenever a Lua function is converted to a C function pointer. This | ||
| 830 | associates the generated callback function pointer with the C type | ||
| 831 | of the function pointer and the Lua function object (closure). | ||
| 832 | </p> | ||
| 833 | <p> | ||
| 834 | This can happen implicitly due to the usual conversions, e.g. when | ||
| 835 | passing a Lua function to a function pointer argument. Or you can use | ||
| 836 | <tt>ffi.cast()</tt> to explicitly cast a Lua function to a | ||
| 837 | C function pointer. | ||
| 838 | </p> | ||
| 839 | <p> | ||
| 840 | Currently only certain C function types can be used as callback | ||
| 841 | functions. Neither C vararg functions nor functions with | ||
| 842 | pass-by-value aggregate argument or result types are supported. There | ||
| 843 | are no restrictions for the kind of Lua functions that can be called | ||
| 844 | from the callback — no checks for the proper number of arguments | ||
| 845 | are made. The return value of the Lua function will be converted to the | ||
| 846 | result type and an error will be thrown for invalid conversions. | ||
| 847 | </p> | ||
| 848 | <p> | ||
| 849 | It's allowed to throw errors across a callback invocation, but it's not | ||
| 850 | advisable in general. Do this only if you know the C function, that | ||
| 851 | called the callback, copes with the forced stack unwinding and doesn't | ||
| 852 | leak resources. | ||
| 853 | </p> | ||
| 854 | |||
| 855 | <h3 id="callback_resources">Callback resource handling</h3> | ||
| 856 | <p> | ||
| 857 | Callbacks take up resources — you can only have a limited number | ||
| 858 | of them at the same time (500 - 1000, depending on the | ||
| 859 | architecture). The associated Lua functions are anchored to prevent | ||
| 860 | garbage collection, too. | ||
| 861 | </p> | ||
| 862 | <p> | ||
| 863 | <b>Callbacks due to implicit conversions are permanent!</b> There is no | ||
| 864 | way to guess their lifetime, since the C side might store the | ||
| 865 | function pointer for later use (typical for GUI toolkits). The associated | ||
| 866 | resources cannot be reclaimed until termination: | ||
| 867 | </p> | ||
| 868 | <pre class="code"> | ||
| 869 | ffi.cdef[[ | ||
| 870 | typedef int (__stdcall *WNDENUMPROC)(void *hwnd, intptr_t l); | ||
| 871 | int EnumWindows(WNDENUMPROC func, intptr_t l); | ||
| 872 | ]] | ||
| 873 | |||
| 874 | -- Implicit conversion to a callback via function pointer argument. | ||
| 875 | local count = 0 | ||
| 876 | ffi.C.EnumWindows(function(hwnd, l) | ||
| 877 | count = count + 1 | ||
| 878 | end, 0) | ||
| 879 | -- The callback is permanent and its resources cannot be reclaimed! | ||
| 880 | -- Ok, so this may not be a problem, if you do this only once. | ||
| 881 | </pre> | ||
| 882 | <p> | ||
| 883 | Note: this example shows that you <em>must</em> properly declare | ||
| 884 | <tt>__stdcall</tt> callbacks on Windows/x86 systems. The calling | ||
| 885 | convention cannot be automatically detected, unlike for | ||
| 886 | <tt>__stdcall</tt> calls <em>to</em> Windows functions. | ||
| 887 | </p> | ||
| 888 | <p> | ||
| 889 | For some use cases it's necessary to free up the resources or to | ||
| 890 | dynamically redirect callbacks. Use an explicit cast to a | ||
| 891 | C function pointer and keep the resulting cdata object. Then use | ||
| 892 | the <a href="ext_ffi_api.html#callback_free"><tt>cb:free()</tt></a> | ||
| 893 | or <a href="ext_ffi_api.html#callback_set"><tt>cb:set()</tt></a> methods | ||
| 894 | on the cdata object: | ||
| 895 | </p> | ||
| 896 | <pre class="code"> | ||
| 897 | -- Explicitly convert to a callback via cast. | ||
| 898 | local count = 0 | ||
| 899 | local cb = ffi.cast("WNDENUMPROC", function(hwnd, l) | ||
| 900 | count = count + 1 | ||
| 901 | end) | ||
| 902 | |||
| 903 | -- Pass it to a C function. | ||
| 904 | ffi.C.EnumWindows(cb, 0) | ||
| 905 | -- EnumWindows doesn't need the callback after it returns, so free it. | ||
| 906 | |||
| 907 | cb:free() | ||
| 908 | -- The callback function pointer is no longer valid and its resources | ||
| 909 | -- will be reclaimed. The created Lua closure will be garbage collected. | ||
| 910 | </pre> | ||
| 911 | |||
| 912 | <h3 id="callback_performance">Callback performance</h3> | ||
| 913 | <p> | ||
| 914 | <b>Callbacks are slow!</b> First, the C to Lua transition itself | ||
| 915 | has an unavoidable cost, similar to a <tt>lua_call()</tt> or | ||
| 916 | <tt>lua_pcall()</tt>. Argument and result marshalling add to that cost. | ||
| 917 | And finally, neither the C compiler nor LuaJIT can inline or | ||
| 918 | optimize across the language barrier and hoist repeated computations out | ||
| 919 | of a callback function. | ||
| 920 | </p> | ||
| 921 | <p> | ||
| 922 | Do not use callbacks for performance-sensitive work: e.g. consider a | ||
| 923 | numerical integration routine which takes a user-defined function to | ||
| 924 | integrate over. It's a bad idea to call a user-defined Lua function from | ||
| 925 | C code millions of times. The callback overhead will be absolutely | ||
| 926 | detrimental for performance. | ||
| 927 | </p> | ||
| 928 | <p> | ||
| 929 | It's considerably faster to write the numerical integration routine | ||
| 930 | itself in Lua — the JIT compiler will be able to inline the | ||
| 931 | user-defined function and optimize it together with its calling context, | ||
| 932 | with very competitive performance. | ||
| 933 | </p> | ||
| 934 | <p> | ||
| 935 | As a general guideline: <b>use callbacks only when you must</b>, because | ||
| 936 | of existing C APIs. E.g. callback performance is irrelevant for a | ||
| 937 | GUI application, which waits for user input most of the time, anyway. | ||
| 938 | </p> | ||
| 939 | <p> | ||
| 940 | For new designs <b>avoid push-style APIs</b> (C function repeatedly | ||
| 941 | calling a callback for each result). Instead <b>use pull-style APIs</b> | ||
| 942 | (call a C function repeatedly to get a new result). Calls from Lua | ||
| 943 | to C via the FFI are much faster than the other way round. Most well | ||
| 944 | designed libraries already use pull-style APIs (read/write, get/put). | ||
| 945 | </p> | ||
| 946 | |||
| 824 | <h2 id="clib">C Library Namespaces</h2> | 947 | <h2 id="clib">C Library Namespaces</h2> |
| 825 | <p> | 948 | <p> |
| 826 | A C library namespace is a special kind of object which allows | 949 | A C library namespace is a special kind of object which allows |
| @@ -1002,7 +1125,6 @@ Other missing features: | |||
| 1002 | <ul> | 1125 | <ul> |
| 1003 | <li>Bit operations for 64 bit types.</li> | 1126 | <li>Bit operations for 64 bit types.</li> |
| 1004 | <li>Arithmetic for <tt>complex</tt> numbers.</li> | 1127 | <li>Arithmetic for <tt>complex</tt> numbers.</li> |
| 1005 | <li>Callbacks from C code to Lua functions.</li> | ||
| 1006 | <li>Passing structs by value to vararg C functions.</li> | 1128 | <li>Passing structs by value to vararg C functions.</li> |
| 1007 | <li><a href="extensions.html#exceptions">C++ exception interoperability</a> | 1129 | <li><a href="extensions.html#exceptions">C++ exception interoperability</a> |
| 1008 | does not extend to C functions called via the FFI, if the call is | 1130 | does not extend to C functions called via the FFI, if the call is |
