Skip to content

BadRyuner/rustishka

Repository files navigation

Rustishka

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.

Overview

C# Side

The library provides a mini interface for the Rust library to interact with the DotNet environment.

private struct BridgeConvention
{
    public delegate* <object, Type> FGetType;
    public delegate* <string, bool, Type> FSearchType;
    public delegate* <Type, int, void*> FGetMethodAtSlot;
    public delegate* <Type, object> FAlloc;
    public delegate* <byte*, int, string> FAllocString;
    public delegate* <Type, int, Array> FAllocArray;
    public delegate* <delegate*<void>, Exception> FTryCatch;
    public delegate* <Exception, void> FThrow;
}

The developer must connect the library to the interface using a function call:

RustishkaBridge.Bridge.ConnectRustModule(string libPath, out IntPtr moduleHandle) // to load lib and connect
// or
RustishkaBridge.Bridge.ConnectRustModule(IntPtr moduleHandle) // connect without loading. Use if the module has already been loaded before.

Rust side

The developer provides an export function with this signature. It will be called in ConnectRustModule

initialize_rustishka!();

Important thing

Structures with class content for Rust have to be created manually.

A tool for obtaining offsets

You can use Sharplab as well.

Features

  • 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: *mut NetObject<SomeType> = allocate(someType); // alloc without constructor invoke !!!
  • Rust lib can call virtual functions:
let someType: *mut NetObject<SystemType> = ...;
let baseType = someType.get_base_type();

This is presented in the form of pseudo wrappers:

define_virtual!(pub, get_base_type, 11, 4, *mut NetObject<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: *mut NetObject<SomeObject> = SomeObject::new(args);

where

impl NetObject<SomeObject> {
   define_function!(pub some_instance_method, 7, self: *mut Self, arg_name: ArgType); // where 7 - slotId
   define_function!(pub some_static_method, 8, arg_name: ArgType);
}
impl SomeObject {
   define_constructor!(pub new, arg_name: ArgType);
}
  • Rust lib can access to static fields
SomeObject::get_cool_static_field();
// where
define_typeof!(SomeObject, "blahblah");
impl SomeObject {
   define_static_field!(pub get_cool_static_field, "CoolStaticField", SomeFieldType);
}
  • Rust lib can use typeof sugar
pub struct SomeObject { }
define_typeof!(SomeObject, "SomeObject AssemblyQualifiedName");
// in method
let ty : *mut NetObject<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.

Examples

C# side

Rust side

TODO

  • 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)

About

Rust + C# = πŸ’˜

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy