diff --git a/CHANGELOG.md b/CHANGELOG.md index a0aad319..2e461373 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ versions. - The optional `register` attribute on `#[register_impl]` works as advertised now (#638) +- API functions for Windows are correctly assigned now for NIF version 2.15 and + above (#635) ### Changed diff --git a/rustler/src/dynamic.rs b/rustler/src/dynamic.rs index 19b0a98c..4eba67c3 100644 --- a/rustler/src/dynamic.rs +++ b/rustler/src/dynamic.rs @@ -45,7 +45,7 @@ impl From for TermType { } pub fn get_type(term: Term) -> TermType { - if cfg!(feature = "nif_version_2_15") && !cfg!(target_family = "windows") { + if cfg!(feature = "nif_version_2_15") { term.get_erl_type().into() } else if term.is_atom() { TermType::Atom diff --git a/rustler_sys/build.rs b/rustler_sys/build.rs index 090fb5c8..d312fe7c 100644 --- a/rustler_sys/build.rs +++ b/rustler_sys/build.rs @@ -139,7 +139,7 @@ impl<'a> ApiBuilder for WinForwardersApiBuilder<'a> { ) .unwrap(); writeln!(self.0, "#[inline]").unwrap(); - writeln!(self.0, "pub unsafe fn {}({})", name, args).unwrap(); + writeln!(self.0, "pub unsafe extern \"C\" fn {}({})", name, args).unwrap(); write_ret(self.0, ret); writeln!(self.0, "{{").unwrap(); writeln!( @@ -845,18 +845,18 @@ fn build_api(b: &mut dyn ApiBuilder, opts: &GenerateOptions) { // 2.15 was introduced in OTP 22 if opts.nif_version >= (2, 15) { + b.dummy("enif_select_x"); b.func( - "ErlNifTermType", - "enif_term_type", - "env: *mut ErlNifEnv, term: ERL_NIF_TERM", + "ERL_NIF_TERM", + "enif_make_monitor_term", + "env: *mut ErlNifEnv, mon: *const ErlNifMonitor", ); - b.func("c_int", "enif_is_pid_undefined", "pid: *const ErlNifPid"); b.func("", "enif_set_pid_undefined", "pid: *mut ErlNifPid"); b.func( - "ERL_NIF_TERM", - "enif_make_monitor_term", - "env: *mut ErlNifEnv, mon: *const ErlNifMonitor", + "ErlNifTermType", + "enif_term_type", + "env: *mut ErlNifEnv, term: ERL_NIF_TERM", ); } @@ -868,15 +868,21 @@ fn build_api(b: &mut dyn ApiBuilder, opts: &GenerateOptions) { // 2.17 was introduced in OTP 26 if opts.nif_version >= (2, 17) { + b.func("c_int", "enif_get_string_length", "env: *mut ErlNifEnv, list: ERL_NIF_TERM, len: *mut c_uint, encoding: ErlNifCharEncoding"); + b.func("c_int", "enif_make_new_atom", "env: *mut ErlNifEnv, name: *const c_char, atom: *mut ERL_NIF_TERM, encoding: ErlNifCharEncoding"); + b.func("c_int", "enif_make_new_atom_len", "env: *mut ErlNifEnv, name: *const c_char, len: size_t, atom: *mut ERL_NIF_TERM, encoding: ErlNifCharEncoding"); b.func( "c_int", "enif_set_option", "env: *mut ErlNifEnv, opt: ErlNifOption", ); - b.func("c_int", "enif_get_string_length", "env: *mut ErlNifEnv, list: ERL_NIF_TERM, len: *mut c_uint, encoding: ErlNifCharEncoding"); - b.func("c_int", "enif_make_new_atom", "env: *mut ErlNifEnv, name: *const c_char, atom: *mut ERL_NIF_TERM, encoding: ErlNifCharEncoding"); - b.func("c_int", "enif_make_new_atom_len", "env: *mut ErlNifEnv, name: *const c_char, len: size_t, atom: *mut ERL_NIF_TERM, encoding: ErlNifCharEncoding"); } + + // If new functions are added for a new OTP version, ensure that *all* functions are added in + // the *correct order*. Failure to do so will result in errors on Windows, as the callback + // handling uses the `TWinDynNifCallbacks` struct. + // + // The correct order can (currently) by derived from the `erl_nif_api_funcs.h` header. } fn get_nif_version_from_features() -> (u32, u32) {