4.5 KiB
FFI Function Signatures
Under this section we discuss the signature requirements of the exported FFI functions.
C-style Name Export
FFI functions must be exported under C names, that is, they must not go through the C++ name mangling mechanism.
In Rust, you need to decorate the function with the #[unsafe(no_mangle)] attribute
together with extern "C", for example:
#[unsafe(no_mangle)]
pub extern "C" fn WFStartup() -> CError {
// Function body omitted...
}
// More FFI functions omitted...
Export Name Style
In this subsection, we discuss the naming style of exported functions.
In this design, there are exactly two styles to choose from. We call them the Windows style and the POSIX style. Either style can be chosen freely, but within a single library the two styles must not be mixed.
We recommend the following selection rule: if your library is Windows-only, choose the Windows style; otherwise, choose the POSIX style.
Windows Style
The Windows style format is <PREFIX><FUNC> for ordinary functions, and
<PREFIX><STRUCT><FUNC> for opaque struct functions.
In the format, <STRUCT> is the name of the opaque struct and <FUNC> is the name
of the function. Both of them must use PascalCase naming.
For <PREFIX>, it is a prefix identifier that is specific to this library. As we
all know, C has no namespace concept, and all functions are exported into the same
space. Therefore, avoiding name collisions between functions is an important task.
By prepending <PREFIX> to the function name, name duplication can be avoided as
much as possible. For this reason, you need to choose <PREFIX> carefully and try
to pick a prefix that is unlikely to collide.
In the Windows style, there are two spellings for <PREFIX>. One is the
all-uppercase style and the other is the style in which only the first letter is
uppercase and all remaining letters are lowercase. Choose according to your own
needs. In addition, the length of <PREFIX> must not exceed 5 characters, and
it must not contain anything other than letters and digits (that is, underscores are
not allowed).
The following examples show some legal and illegal Windows style function names:
| Name | Verdict | Reason |
|---|---|---|
WFStartup |
Legal | An ordinary (non opaque struct) function. |
WFIconGetHandle |
Legal | An opaque struct function whose <STRUCT> is Icon. |
WFWordHandleGetHandle |
Legal | An opaque struct function whose <STRUCT> is WordHandle. |
FlGetMessage |
Legal | Uses a <PREFIX>, which is Fl, that capitalizes only its first letter. |
MyRustGetMessage |
Illegal | <PREFIX>, which is MyRust, does not keep all remaining letters lowercase. |
My_RustGetMessage |
Illegal | <PREFIX> contains an underscore. |
IconGetHandle |
Illegal | Missing <PREFIX>. |
QwertyuiopGetData |
Illegal | <PREFIX>, which is Qwertyuiop, is too long. |
WFget_message |
Illegal | <FUNC>, which is get_message, is not PascalCase. |
WFicon_handleGetMessage |
Illegal | <STRUCT>, which is icon_handle, is not PascalCase. |
POSIX Style
The POSIX style format is <PREFIX>_<FUNC> for ordinary functions, and
<PREFIX>_<STRUCT>_<FUNC> for opaque struct functions.
The <PREFIX>, <STRUCT> and <FUNC> components in the format have the same
meaning as in the Windows style, but the format is different. <STRUCT> and <FUNC>
must use snake_case naming. <PREFIX> must be all lowercase, and it must not contain
anything other than letters and digits (that is, underscores are not allowed). Its
length and selection requirements are the same as in the Windows style.
The following examples show some legal and illegal POSIX style function names:
| Name | Verdict | Reason |
|---|---|---|
wf_startup |
Legal | An ordinary (non opaque struct) function. |
wf_icon_get_handle |
Legal | An opaque struct function whose <STRUCT> is icon. |
wf_word_handle_get_handle |
Legal | An opaque struct function whose <STRUCT> is word_handle. |
Fl_get_message |
Illegal | <PREFIX>, which is Fl, is not all lowercase. |
my_rust_get_message |
Illegal | <PREFIX>, which is my_rust, contains an underscore. |
icon_get_handle |
Illegal | Missing <PREFIX>. |
qwertyuiop_get_data |
Illegal | <PREFIX>, which is qwertyuiop, is too long. |
wf_GetMessage |
Illegal | <FUNC>, which is GetMessage, is not snake_case. |
wf_Icon_get_message |
Illegal | <STRUCT>, which is Icon, is not snake_case. |