Skip to content

String parameter of a callback function gets messed when passed from DLL (Rust) to Java #335

@Revxrsal

Description

@Revxrsal

o/ I'm migrating from JNA to JNR, and almost everything works fine. However, I've run into a really odd bug when using callback functions. I've built a minimal project that reproduces it. The JNA equivilent works fine.

Note: My native library is written in Rust

How to reproduce

  1. Install the native library (see platform artifacts)
  2. Load the library
  3. Try to call it from Java.

Java:

import jnr.ffi.LibraryLoader;
import jnr.ffi.annotations.Delegate;

public class Main {

    public interface Natives {

        void simple_callback(SimpleCallback callback);

        interface SimpleCallback {
            @Delegate
            void invoke(String value);
        }

        static Natives load() {
            return LibraryLoader
                    .create(Natives.class)
                    .load("<path to the library>");
        }
    }

    public static void main(String[] args) {
        Natives natives = Natives.load();
        for (int i = 0; i < 10; i++) {
            natives.simple_callback(System.out::println);
        }
    }
}

Rust:

use std::ffi::{c_char, CString};
use std::mem;

/// Converts a Rust string to a Java string
pub fn to_java_string(string: &str) -> *const c_char {
    let cs = CString::new(string.as_bytes()).unwrap();
    let ptr = cs.as_ptr();
    // Tell Rust not to clean up the string while we still have a pointer to it.
    // Otherwise, we'll get a segfault.
    mem::forget(cs);
    ptr
}

#[no_mangle]
extern fn simple_callback(callback: extern fn(*const c_char)) {
    let value = "Any string value";
    callback(to_java_string(&value));
}

The output:

Any string value
Any string value
Any string value lG�|�  ���� $�?	 � dRTypeCache �   |�  ���� %�� �|�
Any string value
Any string value
��hNG�|�  �,0�|�
Any string value
Any string value |��|�  A���|���
Any string value
Any string value

(The corruption is different every time)
Any idea what could be causing this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions