Stream: cranelift

Topic: How to import external C functions


view this post on Zulip Engineer in a box (May 17 2026 at 19:56):

I've been trying to import malloc, but the documentation is incredibly unclear to me, so I was hoping I could get some help here.
I've this got so far, but I'm pretty sure this doesn't work

let malloc_ref = {
    let sig = Signature {
        params: vec![AbiParam::new(word_type)],
        returns: vec![AbiParam::new(word_type)],
        #[cfg(target_family = "unix")]
        call_conv: CallConv::SystemV,
        #[cfg(target_os = "windows")]
        call_conv: CallConv::WindowsFastcall,
        #[cfg(not(any(target_os = "windows", target_family = "unix")))]
        call_conv: compile_error!("this crate only supports windows and unix based operating systems"),
    };
    let id = module.declare_function("malloc", Linkage::Import, &sig).ok()?;
    let sigref = fn_builder.import_signature(sig);
    let ext_name_ref = fn_builder.func.declare_imported_user_function(UserExternalName::default());
    fn_builder.import_function(ExtFuncData {
        name: ExternalName::User(ext_name_ref),
        signature: sigref,
        colocated: false,
        patchable: false
    })
};

Any help would be appreciated :3

view this post on Zulip Floppy (May 18 2026 at 02:23):

That looks correct. (although you should only be using declare_function once for it and then in any other function that uses it you do import_function)

Is this for JIT or are you linking into a binary?

view this post on Zulip Floppy (May 18 2026 at 02:25):

also ideally you should get the calling convention from TargetIsa::default_call_conv and set the TargetIsa to windows/unix to make it more portable.

view this post on Zulip bjorn3 (May 18 2026 at 07:26):

You should use module.declare_func_in_func() instead of func.import_function(). UserExternalName::default() is not a valid name.


Last updated: Jun 01 2026 at 09:49 UTC