title: Calling Rust from Java
body: <p>I am using Rust 1.0 beta and was able to create a small example for calling functions written in Rust from Java. I simply compiled the following Rust code in mylib.rs using rustc which produces a mylib.dll on Windows:</p>
  
  <pre><code>#![crate_type = "dylib"]
  use std::any::Any;
  
  #[no_mangle]
  pub extern fn Java_tests_Test_hello(env: *const Any, jclass: *const Any) {
      println!("hello from rust");
  }
  
  #[no_mangle]
  pub extern fn Java_tests_Test_sum(env: *const Any, jclass: *const Any, a: i32, b: i32) -&gt; i32 {
      return a + b;
  }
  </code></pre>
  
  <p>Then I can call these functions from a Java class tests.Test:</p>
  
  <pre><code>package tests;
  
  import java.io.File;
  
  public class Test {
  
      public static native void hello();
  
      public static native int sum(int a, int b);
  
      public static void main(String[] args) {
          File f = new File("mylib.dll");
          System.load(f.getAbsolutePath());
          Test.hello();
          System.out.println(Test.sum(20, 22));
      }
  }
  </code></pre>
  
  <p>Running the Java main prints the expected result:</p>
  
  <pre><code>hello from rust
  42
  </code></pre>
  
  <p>In the Rust methods I declared <code>env</code> as a pointer to the <code>Any</code> type but in reality it is a C struct with pointers to functions as described in the <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html" rel="noreferrer">documentation (Code example 4-1)</a> which are required to exchange data with the Java runtime. </p>
  
  <p>From this <a href="https://stackoverflow.com/a/26118378/599575">answer</a> I understood that such structs with function pointers should have a counterpart in the Rust code to call these functions. So I tried to implement such a struct setting all field values to <code>*mut Any</code> except for the <code>GetVersion</code> field: </p>
  
  <pre><code>#[repr(C)]
  pub struct JavaEnv {
  
      reserved0: *mut Any,
      reserved1: *mut Any,
      reserved2: *mut Any,
      reserved3: *mut Any,
      GetVersion: extern "C" fn(env: *mut JavaEnv) -&gt; i32,
  
      DefineClass: *mut Any,
      FindClass: *mut Any,  
      …
  </code></pre>
  
  <p>When I call the following function from Java which should call the GetVersion function, the JVM crashes:</p>
  
  <pre><code>#[no_mangle]
  pub extern fn Java_tests_Test_helloJre(jre: *mut JavaEnv, class: *const Any) {
      unsafe {
          let v = ((*jre).GetVersion)(jre);
          println!("version: {:?}", v);
      }
  }
  </code></pre>
  
  <p>How should I call the GetVersion function correctly? Note that I am really new to this kind of stuff so please feel free to edit this question if required.</p>