Let's say I have some Rust function which I want to expose through FFI. There are lots of possibilities depending on the environment and the language I want to interface to.
For example, string arguments may be pascal-lengthed, separately-lengthed or null-terminated. Characters may be ASCII, UTF8/16/32. The calling convention may be stdcall or cdecl. The size of the ints and bools are context dependent. The exported name may be camel case or snake case, and may need an initial underscore.
I may want to expose just one of these interface types, depending on compile skips, or I may want to expose more than one in the same dynamic library.
This sounds like a job for Rust macros. Some questions, then:
I guess I should come clean about my actual use-case here. I am writing Excel addins in Rust. Excel requires strings that are UTF16 and preceded by their length, like Pascal strings. Thus I don't have a choice about string encoding. The same is likely to be true for other applications.
I have used cbindgen for generating C header files from Rust functions, but I have first ensured that the Rust functions are defined with C-friendly types from FFI, and avoiding structs and tuples. Otherwise you'd end up with an interface that was pretty hard to use from languages like Python.
My idea here is to use macros to generate thunk functions that wrap the hand-written Rust methods, converting &str into friendlier types using CStr/CString etc.
To partly answer my own question, it is possible to use Rust macros to generate an interface in this way, though only using the nightly build of the Rust compiler. A good example of someone doing just this is https://github.com/PyO3
This produces a python-friendly interface from rust functions and structs. I think it would be possible to use the same techniques to produce interfaces that were friendly to other language environments, such as Microsoft environments using pascal-lengthed UTF16 strings.
I shall experiment, and if I get anywhere I shall post back to this thread.