This project offers cool ways to interact between these super safe & supe fast languages!
Rust <===> C# interop at the highest level!
This effect is created by using special libraries on the C# side and on the Rust side.
The library provides a mini interface for the Rust library to interact with the DotNet environment.
privatestructBridgeConvention{publicdelegate*<object,Type>FGetType;publicdelegate*<string,bool,Type>FSearchType;publicdelegate*<Type,int,void*>FGetMethodAtSlot;publicdelegate*<Type,object>FAlloc;publicdelegate*<byte*,int,string>FAllocString;publicdelegate*<Type,int,Array>FAllocArray;publicdelegate*<delegate*<void>,Exception>FTryCatch;publicdelegate*<Exception,void>FThrow;}The developer must connect the library to the interface using a function call:
RustishkaBridge.Bridge.ConnectRustModule(stringlibPath,outIntPtrmoduleHandle)// to load lib and connect// or
RustishkaBridge.Bridge.ConnectRustModule(IntPtrmoduleHandle)// connect without loading. Use if the module has already been loaded before.The developer provides an export function with this signature. It will be called in ConnectRustModule
initialize_rustishka!();Structures with class content for Rust have to be created manually.
You can use Sharplab as well.
- Rust lib can search for a type in the DotNet runtime:
let integer_type = search_type_cached(&String::from("System.Int32"),false);- Rust lib can allocate objects & arrays:
let someType = search_type_cached(&someTypeAQN,false);let obj:*mutNetObject<SomeType> = allocate(someType);// alloc without constructor invoke !!!- Rust lib can call virtual functions:
let someType:*mutNetObject<SystemType> = ...;let baseType = someType.get_base_type();This is presented in the form of pseudo wrappers:
define_virtual!(pub, get_base_type,11,4,*mutNetObject<SystemType>);where: 11 - row eq slotId / 8, 4 - index eq slotId % 8
- Rust lib can call non-virtual instance and static functions.
someObject.some_instance_method(args);NetObject::<SomeObject>::some_static_method(args)let val:*mutNetObject<SomeObject> = SomeObject::new(args);where
implNetObject<SomeObject>{define_function!(pub some_instance_method,7,self:*mutSelf, arg_name:ArgType);// where 7 - slotIddefine_function!(pub some_static_method,8, arg_name:ArgType);}implSomeObject{define_constructor!(pub new, arg_name:ArgType);}- Rust lib can access to static fields
SomeObject::get_cool_static_field();// wheredefine_typeof!(SomeObject,"blahblah");implSomeObject{define_static_field!(pub get_cool_static_field,"CoolStaticField",SomeFieldType);}- Rust lib can use typeof sugar
pubstructSomeObject{}define_typeof!(SomeObject,"SomeObject AssemblyQualifiedName");// in methodlet ty :*mutNetObject<SystemType> = SomeObject::type_of();- Rust lib can easily alloc managed arrays
managed_array!(ElementType, elements num, elements);// ex:managed_array!(i32,5,0,1,2,3,4);managed_array!(SystemType,2,i32::type_of(),f32::type_of());- Rust lib can use almost all of .NET Reflection's features! (Even use DynamicMethod!)
As you can see: it`s very human design, very easy to use.
- Add support for field access
- .Net type inheritance in Rust by creating a custom type via .Net TypeBuilder & overriding methodtable entries.
- Source generators (atm it's scary Rustishka.Tools)