first commit
This commit is contained in:
commit
e2c095af41
34 changed files with 667 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
49
Cargo.lock
generated
Normal file
49
Cargo.lock
generated
Normal file
|
@ -0,0 +1,49 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.157"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "374af5f94e54fa97cf75e945cce8a6b201e88a1a07e688b47dfd2a59c66dbd86"
|
||||
|
||||
[[package]]
|
||||
name = "makepad-android-state"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd004cda8be459fd76954218b76a1249a079fb9360bbca4e724cb7ddb2962857"
|
||||
dependencies = [
|
||||
"makepad-jni-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "makepad-jni-sys"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9775cbec5fa0647500c3e5de7c850280a88335d1d2d770e5aa2332b801ba7064"
|
||||
|
||||
[[package]]
|
||||
name = "rust-interop"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"makepad-android-state",
|
||||
"makepad-jni-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
30
Cargo.toml
Normal file
30
Cargo.toml
Normal file
|
@ -0,0 +1,30 @@
|
|||
[package]
|
||||
name = "rust-interop"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
name = "rust_interop"
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
# [bin]
|
||||
# name = "_rust_interop"
|
||||
# path = "examples/interop.rs"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.157"
|
||||
makepad-jni-sys = "0.4.0"
|
||||
makepad-android-state = "0.1.0"
|
||||
# makepad-android-state = { path = "../makepad/libs/android_state", version = "0.1.0" }
|
||||
# makepad-jni-sys = { path = "../makepad/libs/jni-sys", version = "0.4.0" }
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.1.13"
|
||||
|
||||
[build]
|
||||
build = "build.rs"
|
||||
|
||||
[features]
|
||||
default = ["android-result"]
|
||||
android-result = []
|
0
README.md
Normal file
0
README.md
Normal file
99
build.rs
Normal file
99
build.rs
Normal file
|
@ -0,0 +1,99 @@
|
|||
use std::{path::Path, process::Command};
|
||||
|
||||
fn main() {
|
||||
compile_java();
|
||||
compile_c();
|
||||
compile_objc();
|
||||
compile_swift();
|
||||
link_libraries();
|
||||
|
||||
// Run the Java command after the build
|
||||
if let Err(e) = run_java_command() {
|
||||
panic!("Failed to run Java command: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_java() {
|
||||
// Compile Java code using `javac`
|
||||
println!("cargo:rerun-if-changed=java/HelloWorld.java");
|
||||
let java_compile_status = Command::new("javac")
|
||||
.arg("-d")
|
||||
.arg("java") // Output directory for .class files
|
||||
.arg("java/HelloWorld.java")
|
||||
.status()
|
||||
.expect("Failed to compile Java code");
|
||||
if !java_compile_status.success() {
|
||||
panic!("Java compilation failed");
|
||||
}
|
||||
}
|
||||
fn run_java_command() -> std::io::Result<()> {
|
||||
let java_class_path = "./java";
|
||||
let java_library_path = "./target/release";
|
||||
|
||||
Command::new("java")
|
||||
.arg("-cp")
|
||||
.arg(java_class_path)
|
||||
.arg("-Djava.library.path")
|
||||
.arg(java_library_path)
|
||||
.arg("HelloWorld")
|
||||
.status()
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
fn compile_c() {
|
||||
// Compile C code
|
||||
cc::Build::new()
|
||||
.file("c/example.c")
|
||||
.include("c") // Include directory for header files
|
||||
.compile("example");
|
||||
}
|
||||
|
||||
fn compile_objc() {
|
||||
// Compile Objective-C code
|
||||
cc::Build::new()
|
||||
.file("objc/MyClass.m") // Path to your Objective-C source file
|
||||
.includes(&["objc"]) // Include necessary directories
|
||||
.flag("-ObjC") // Objective-C flag for linking all categories and classes
|
||||
.compile("MyClass"); // Name of the compiled library (without extension)
|
||||
|
||||
// Link to the Objective-C runtime
|
||||
println!("cargo:rustc-link-lib=objc"); // Link against the Objective-C runtime library
|
||||
|
||||
// Specify the path to the Objective-C header files
|
||||
println!("cargo:include=objc"); // Include directory for headers
|
||||
}
|
||||
|
||||
fn compile_swift() {
|
||||
// Compile Swift code using `swiftc`
|
||||
println!("cargo:rerun-if-changed=swift/MySwiftClass.swift");
|
||||
let swift_output_dir = "swift";
|
||||
let swift_file = "swift/MySwiftClass.swift";
|
||||
let swift_lib = "libSwiftModule.dylib";
|
||||
|
||||
// Ensure swift directory exists
|
||||
if !Path::new(swift_output_dir).exists() {
|
||||
std::fs::create_dir_all(swift_output_dir).expect("Failed to create Swift output directory");
|
||||
}
|
||||
|
||||
Command::new("swiftc")
|
||||
.args(&[
|
||||
"-emit-library",
|
||||
"-emit-module",
|
||||
"-module-name",
|
||||
"SwiftModule",
|
||||
"-o",
|
||||
swift_lib,
|
||||
swift_file,
|
||||
])
|
||||
.current_dir(swift_output_dir)
|
||||
.status()
|
||||
.expect("Failed to compile Swift code");
|
||||
}
|
||||
|
||||
fn link_libraries() {
|
||||
// Link to the compiled C, Objective-C, and Swift libraries
|
||||
println!("cargo:rustc-link-lib=static=example");
|
||||
println!("cargo:rustc-link-lib=objc");
|
||||
println!("cargo:rustc-link-lib=dylib=SwiftModule"); // Link the Swift library
|
||||
println!("cargo:rustc-link-search=native=swift"); // Search path for Swift library
|
||||
}
|
9
c/example.c
Normal file
9
c/example.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include "example.h"
|
||||
|
||||
int add(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
void print_message() {
|
||||
printf("Hello from C!\n");
|
||||
}
|
9
c/example.h
Normal file
9
c/example.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef EXAMPLE_H
|
||||
#define EXAMPLE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int add(int a, int b);
|
||||
void print_message();
|
||||
|
||||
#endif // EXAMPLE_H
|
8
examples/c.rs
Normal file
8
examples/c.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
// examples/c.rs
|
||||
// sudo cargo run --example c --release
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
rust_interop::add_and_print(2, 4); // Call the function from rust_interop
|
||||
}
|
||||
}
|
25
examples/java.rs
Normal file
25
examples/java.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
// Run the Java command after the build
|
||||
if let Err(e) = run_java_command() {
|
||||
panic!("Failed to run Java command: {:?}", e);
|
||||
}
|
||||
}
|
||||
fn run_java_command() -> std::io::Result<()> {
|
||||
let java_class_path = "./java";
|
||||
let java_library_path = "./target/release";
|
||||
|
||||
let status = Command::new("java")
|
||||
.arg("-cp")
|
||||
.arg(java_class_path)
|
||||
.arg(format!("-Djava.library.path={}", java_library_path))
|
||||
.arg("HelloWorld")
|
||||
.status()?;
|
||||
|
||||
if !status.success() {
|
||||
panic!("Java execution failed");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
9
examples/swift.rs
Normal file
9
examples/swift.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
use rust_interop::swift::swiftFunction;
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
// let result = rust_interop::swift::swiftFunction();
|
||||
let result = swiftFunction();
|
||||
println!("Result from Swift function: {}", result);
|
||||
}
|
||||
}
|
24
extra.txt
Normal file
24
extra.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
javac -version
|
||||
sudo cargo build --release
|
||||
sudo cargo run --example c --release
|
||||
sudo cargo run --example java --release
|
||||
sudo cargo run --example swift --release
|
||||
|
||||
|
||||
This will generate a com/example/MyJavaClass.class file.
|
||||
javac -d . MyJavaClass.java
|
||||
|
||||
javac HelloWorld.java
|
||||
|
||||
javac -h . java/HelloWorld.java
|
||||
java -Djava.library.path=./target/release -cp java HelloWorld
|
||||
|
||||
|
||||
javac -h ./java java/HelloWorld.java
|
||||
cargo build --release
|
||||
java -cp ./java -Djava.library.path=./target/release HelloWorld
|
||||
java -verbose:jni -cp ./java -Djava.library.path=./target/release HelloWorld
|
||||
chmod +x ./target/release/librust_jni_example.dylib
|
||||
|
||||
|
||||
swiftc -emit-library -emit-module -module-name SwiftModule -o libSwiftModule.dylib swift/MySwiftClass.swift
|
BIN
java/HelloWorld.class
Normal file
BIN
java/HelloWorld.class
Normal file
Binary file not shown.
21
java/HelloWorld.h
Normal file
21
java/HelloWorld.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class HelloWorld */
|
||||
|
||||
#ifndef _Included_HelloWorld
|
||||
#define _Included_HelloWorld
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: HelloWorld
|
||||
* Method: callRustFunction
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_HelloWorld_callRustFunction
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
17
java/HelloWorld.java
Normal file
17
java/HelloWorld.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
// java/HelloWorld.java
|
||||
public class HelloWorld {
|
||||
static {
|
||||
System.loadLibrary("rust_interop");
|
||||
}
|
||||
|
||||
public native void callRustFunction();
|
||||
|
||||
public String getGreeting() {
|
||||
return "Hello from Java!";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
HelloWorld hw = new HelloWorld();
|
||||
hw.callRustFunction();
|
||||
}
|
||||
}
|
14
java/Main.java
Normal file
14
java/Main.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
// java/Main.java
|
||||
public class Main {
|
||||
static {
|
||||
System.loadLibrary("rust_jni_example");
|
||||
}
|
||||
|
||||
private static native void call_java_from_rust();
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Calling Rust function...");
|
||||
call_java_from_rust();
|
||||
System.out.println("Rust function call completed.");
|
||||
}
|
||||
}
|
0
javascript/index.js
Normal file
0
javascript/index.js
Normal file
20
objc/MyClass.h
Normal file
20
objc/MyClass.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
// swift/MyClass.h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Declare functions to be used by Rust
|
||||
void create_object();
|
||||
void call_method();
|
||||
const char* get_message();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@interface MyClass : NSObject
|
||||
- (void)printMessage;
|
||||
- (NSString *)getMessage;
|
||||
@end
|
35
objc/MyClass.m
Normal file
35
objc/MyClass.m
Normal file
|
@ -0,0 +1,35 @@
|
|||
// swift/MyClass.m
|
||||
#import "MyClass.h"
|
||||
|
||||
@implementation MyClass
|
||||
|
||||
- (void)printMessage {
|
||||
NSLog(@"Hello from Objective-C!");
|
||||
}
|
||||
|
||||
- (NSString *)getMessage {
|
||||
return @"Hello from Objective-C!";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// C-compatible interface functions
|
||||
static MyClass *myClassInstance = nil;
|
||||
|
||||
void create_object() {
|
||||
myClassInstance = [[MyClass alloc] init];
|
||||
}
|
||||
|
||||
void call_method() {
|
||||
if (myClassInstance) {
|
||||
[myClassInstance printMessage];
|
||||
}
|
||||
}
|
||||
|
||||
const char* get_message() {
|
||||
if (myClassInstance) {
|
||||
NSString *message = [myClassInstance getMessage];
|
||||
return [message UTF8String];
|
||||
}
|
||||
return "";
|
||||
}
|
6
objc/objc_wrapper.h
Normal file
6
objc/objc_wrapper.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef OBJC_WRAPPER_H
|
||||
#define OBJC_WRAPPER_H
|
||||
|
||||
void call_objc_function();
|
||||
|
||||
#endif // OBJC_WRAPPER_H
|
7
objc/objc_wrapper.m
Normal file
7
objc/objc_wrapper.m
Normal file
|
@ -0,0 +1,7 @@
|
|||
#import "objc_wrapper.h"
|
||||
#import "MyClass.h"
|
||||
|
||||
void call_objc_function() {
|
||||
MyClass *obj = [[MyClass alloc] init];
|
||||
[obj helloFromObjectiveC];
|
||||
}
|
5
src/c.rs
Normal file
5
src/c.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
// Declare external functions from C
|
||||
extern "C" {
|
||||
pub fn add(a: i32, b: i32) -> i32;
|
||||
pub fn print_message();
|
||||
}
|
188
src/java.rs
Normal file
188
src/java.rs
Normal file
|
@ -0,0 +1,188 @@
|
|||
use makepad_android_state::get_java_vm;
|
||||
use makepad_jni_sys::{jint, jobject, JavaVM, _jmethodID, _jobject};
|
||||
use std::{
|
||||
ffi::{CStr, CString},
|
||||
ptr,
|
||||
};
|
||||
|
||||
use makepad_jni_sys as jni_sys;
|
||||
|
||||
static mut _ACTIVITY: jobject = ptr::null_mut();
|
||||
static mut VM: *mut JavaVM = ptr::null_mut();
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn call_java_from_rust() {
|
||||
unsafe {
|
||||
// Get the JavaVM instance
|
||||
if get_java_vm().is_null() {
|
||||
eprintln!("Failed to get JavaVM");
|
||||
return;
|
||||
}
|
||||
|
||||
let env = attach_jni_env();
|
||||
|
||||
let class_name = CString::new("HelloWorld").unwrap();
|
||||
let method_name = CString::new("getGreeting").unwrap();
|
||||
let method_sig = CString::new("()Ljava/lang/String;").unwrap();
|
||||
let (obj, method_id) = new_object(env, class_name, method_name, method_sig);
|
||||
|
||||
// let method_name = CString::new("getGreeting").unwrap();
|
||||
// let method_sig = CString::new("()Ljava/lang/String;").unwrap();
|
||||
// let method_id =
|
||||
// (**env).GetMethodID.unwrap()(env, class, method_name.as_ptr(), method_sig.as_ptr());
|
||||
// if method_id.is_null() {
|
||||
// eprintln!("Failed to find getGreeting method.");
|
||||
// detach_current_thread();
|
||||
// return;
|
||||
// }
|
||||
// println!("Found getGreeting method.");
|
||||
|
||||
let result = (**env).CallObjectMethod.unwrap()(env, obj, method_id);
|
||||
if result.is_null() {
|
||||
eprintln!("Failed to call getGreeting method.");
|
||||
detach_current_thread();
|
||||
return;
|
||||
}
|
||||
println!("Called getGreeting method.");
|
||||
|
||||
let result_str_ptr = (**env).GetStringUTFChars.unwrap()(env, result, ptr::null_mut());
|
||||
if result_str_ptr.is_null() {
|
||||
eprintln!("Failed to convert Java string to Rust string.");
|
||||
detach_current_thread();
|
||||
return;
|
||||
}
|
||||
|
||||
let result_str = CStr::from_ptr(result_str_ptr)
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
println!("Result from Java: {}", result_str);
|
||||
|
||||
(**env).ReleaseStringUTFChars.unwrap()(env, result, result_str_ptr);
|
||||
|
||||
// Detach the current thread from the JVM
|
||||
detach_current_thread();
|
||||
|
||||
// Note: We're not destroying the JVM here because it's generally not recommended
|
||||
// to destroy the JVM unless you're absolutely sure you want to terminate the entire Java environment.
|
||||
// If you do need to destroy the JVM, you can uncomment the following code:
|
||||
|
||||
/*
|
||||
// Destroy the JVM
|
||||
let destroy_res = (**vm).DestroyJavaVM.unwrap()(vm);
|
||||
if destroy_res != 0 {
|
||||
eprintln!("Failed to destroy JVM.");
|
||||
} else {
|
||||
println!("Destroyed JVM.");
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn new_object(
|
||||
env: *mut jni_sys::JNIEnv,
|
||||
class_name: CString,
|
||||
method_name: CString,
|
||||
method_sig: CString,
|
||||
) -> (*mut _jobject, *mut _jmethodID) {
|
||||
let find_class = (**env).FindClass.unwrap();
|
||||
let get_method_id = (**env).GetMethodID.unwrap();
|
||||
let new_object_here = (**env).NewObject.unwrap();
|
||||
|
||||
let class = find_class(env, class_name.as_ptr() as _);
|
||||
if class.is_null() {
|
||||
eprintln!("Failed to find {:?} class.", class_name);
|
||||
detach_current_thread();
|
||||
// return;
|
||||
}
|
||||
println!("Found {:?} class.", class_name);
|
||||
|
||||
let method_id = get_method_id(
|
||||
env,
|
||||
class,
|
||||
method_name.as_ptr() as _,
|
||||
method_sig.as_ptr() as _,
|
||||
);
|
||||
if method_id.is_null() {
|
||||
eprintln!("Failed to find constructor method.");
|
||||
detach_current_thread();
|
||||
// return;
|
||||
}
|
||||
println!("Found constructor method.");
|
||||
|
||||
let obj = new_object_here(env, class, method_id);
|
||||
if obj.is_null() {
|
||||
eprintln!("Failed to create {:?} object.", class_name);
|
||||
detach_current_thread();
|
||||
// return;
|
||||
}
|
||||
println!("Created {:?} object.", class_name);
|
||||
(obj, method_id)
|
||||
}
|
||||
|
||||
pub unsafe fn detach_current_thread() {
|
||||
// eprintln!("Failed to find constructor method.");
|
||||
let detach_res = (**get_java_vm()).DetachCurrentThread.unwrap()(get_java_vm());
|
||||
if detach_res != 0 {
|
||||
eprintln!(
|
||||
"Failed to detach current thread. Error code: {}. Ensure the thread is properly attached and the JVM state is correct.",
|
||||
detach_res
|
||||
);
|
||||
} else {
|
||||
println!("Detached current thread from JVM.");
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn attach_jni_env() -> *mut jni_sys::JNIEnv {
|
||||
let mut env: *mut jni_sys::JNIEnv = std::ptr::null_mut();
|
||||
let attach_current_thread = (**get_java_vm()).AttachCurrentThread.unwrap();
|
||||
|
||||
let res = attach_current_thread(get_java_vm(), &mut env, std::ptr::null_mut());
|
||||
// assert!(res == 0);
|
||||
if res != 0 || env.is_null() {
|
||||
eprintln!(
|
||||
"Failed to attach current thread or env is null. Error code: {}",
|
||||
res
|
||||
);
|
||||
return env;
|
||||
}
|
||||
println!("Attached current thread to JVM.");
|
||||
env
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_attach_detach() {
|
||||
unsafe {
|
||||
if get_java_vm().is_null() {
|
||||
eprintln!("Failed to get JavaVM");
|
||||
return;
|
||||
}
|
||||
|
||||
let _ = attach_jni_env();
|
||||
|
||||
detach_current_thread();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Java_HelloWorld_callRustFunction(_env: *mut jni_sys::JNIEnv, _obj: jobject) {
|
||||
// Implementation of your native method
|
||||
// println!("Rust function callRustFunction is called from Java!");
|
||||
// Optionally, you can call other Rust functions like call_java_from_rust() here if needed
|
||||
call_java_from_rust();
|
||||
// test_attach_detach();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn JNI_OnLoad(vm: *mut JavaVM, _reserved: *const std::ffi::c_void) -> jint {
|
||||
unsafe {
|
||||
VM = vm;
|
||||
}
|
||||
jni_sys::JNI_VERSION_1_6
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn JNI_OnUnload(_vm: *mut JavaVM, _reserved: *const std::ffi::c_void) {
|
||||
// unsafe {
|
||||
// // Optionally, you can add cleanup code here
|
||||
// }
|
||||
}
|
30
src/lib.rs
Normal file
30
src/lib.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
//File lib.rs
|
||||
|
||||
// src/lib.rs
|
||||
// src/java.rs
|
||||
// src/rust_interop.rs
|
||||
// src/c.rs
|
||||
// examples/c.rs
|
||||
// examples/java.rs
|
||||
// examples/swift.rs
|
||||
// src/main.rs
|
||||
// src/objc.rs
|
||||
// src/swift
|
||||
// c/example.h
|
||||
// c/example.c
|
||||
// java/HelloWorld.java
|
||||
// java/HelloWorld.class
|
||||
// objc/MyClass.h
|
||||
// objc/MyClass.m
|
||||
// swift/MySwiftClass.swift
|
||||
// swift/SwiftModule.h
|
||||
// swift/module.modulemap
|
||||
// Cargo.toml
|
||||
// build.rs
|
||||
pub mod c;
|
||||
pub mod java;
|
||||
pub mod objc;
|
||||
pub mod rust_interop;
|
||||
pub mod swift;
|
||||
|
||||
pub use rust_interop::add_and_print; // Re-export the function for easier access
|
7
src/objc.rs
Normal file
7
src/objc.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
use std::ffi::c_char;
|
||||
|
||||
extern "C" {
|
||||
pub fn create_object();
|
||||
pub fn call_method();
|
||||
pub fn get_message() -> *const c_char;
|
||||
}
|
10
src/rust_interop.rs
Normal file
10
src/rust_interop.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
// src/rust_interop.rs
|
||||
pub use crate::c::{add, print_message};
|
||||
|
||||
pub fn add_and_print(a: i32, b: i32) {
|
||||
let result = unsafe { add(a, b) };
|
||||
println!("The result of adding {} and {} is: {}", a, b, result);
|
||||
unsafe {
|
||||
print_message();
|
||||
}
|
||||
}
|
8
src/swift.rs
Normal file
8
src/swift.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
use libc::c_int;
|
||||
// use std::ffi::CString;
|
||||
// use std::os::raw::c_void;
|
||||
// use std::ptr;
|
||||
|
||||
extern "C" {
|
||||
pub fn swiftFunction() -> c_int;
|
||||
}
|
8
swift/MySwiftClass.swift
Normal file
8
swift/MySwiftClass.swift
Normal file
|
@ -0,0 +1,8 @@
|
|||
// swift/MySwiftClass.swift
|
||||
import Foundation
|
||||
|
||||
@_silgen_name("swift_function")
|
||||
func swiftFunction() -> Int32 {
|
||||
print("Swift function called")
|
||||
return 42
|
||||
}
|
9
swift/SwiftModule.abi.json
Normal file
9
swift/SwiftModule.abi.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ABIRoot": {
|
||||
"kind": "Root",
|
||||
"name": "TopLevel",
|
||||
"printedName": "TopLevel",
|
||||
"json_format_version": 8
|
||||
},
|
||||
"ConstValues": []
|
||||
}
|
15
swift/SwiftModule.h
Normal file
15
swift/SwiftModule.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
// swift/SwiftModule.h
|
||||
#ifndef SWIFT_MODULE_H
|
||||
#define SWIFT_MODULE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t swiftFunction();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SWIFT_MODULE_H
|
BIN
swift/SwiftModule.swiftdoc
Normal file
BIN
swift/SwiftModule.swiftdoc
Normal file
Binary file not shown.
BIN
swift/SwiftModule.swiftmodule
Normal file
BIN
swift/SwiftModule.swiftmodule
Normal file
Binary file not shown.
BIN
swift/SwiftModule.swiftsourceinfo
Normal file
BIN
swift/SwiftModule.swiftsourceinfo
Normal file
Binary file not shown.
BIN
swift/libSwiftModule.dylib
Executable file
BIN
swift/libSwiftModule.dylib
Executable file
Binary file not shown.
4
swift/module.modulemap
Normal file
4
swift/module.modulemap
Normal file
|
@ -0,0 +1,4 @@
|
|||
module SwiftModule {
|
||||
header "SwiftModule.h"
|
||||
export *
|
||||
}
|
Loading…
Reference in a new issue