Skip to content

Instantly share code, notes, and snippets.

@paxbun
Last active July 11, 2020 15:53
Show Gist options
  • Select an option

  • Save paxbun/e7e4acb3851ea362bad5280f29e65aa3 to your computer and use it in GitHub Desktop.

Select an option

Save paxbun/e7e4acb3851ea362bad5280f29e65aa3 to your computer and use it in GitHub Desktop.
C# and Rust interop example
[package]
name = "nok-internal"
version = "0.1.0"
authors = ["Chanjung Kim <freiyer.paxbun@gmail.com>"]
edition = "2018"
[dependencies]
num = "0.3.0"
[lib]
name = "internal"
path = "src/lib.rs"
crate-type = ["dylib"]
#[repr(C)]
pub struct StringLengths {
utf8: i32,
utf16: i32,
}
pub unsafe fn get_str_lens_internal<T: num::PrimInt>(s: *const T) -> i32 {
let mut rtn = 0;
let mut ptr = s;
while !(*ptr).is_zero() {
ptr = ptr.offset(1);
rtn = rtn + 1;
}
rtn
}
/// Returns the length of the string in UTF8 form.and UTF16 form
#[no_mangle]
pub unsafe extern "C" fn get_str_lens(s1: *const i8, s2: *const i16) -> StringLengths {
StringLengths {
utf8: get_str_lens_internal(s1),
utf16: get_str_lens_internal(s2),
}
}
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Nok
{
struct StringLengths
{
[MarshalAs(UnmanagedType.I4)]
int utf8;
[MarshalAs(UnmanagedType.I4)]
int utf16;
public override string ToString()
{
return $"{{ UTF8: {utf8}, UTF16: {utf16} }}";
}
}
static class StringExtensions
{
[DllImport("nok-internal", EntryPoint = "get_str_lens")]
private extern static StringLengths GetStringLengths(
[MarshalAs(UnmanagedType.LPUTF8Str)] string utf8,
[MarshalAs(UnmanagedType.LPWStr)] string utf16);
public static StringLengths GetStringLengths(this string s)
{
return GetStringLengths(s, s);
}
public static void PrintStringLengths(this string s)
{
Console.WriteLine("UTF8 Length of \"{0}\": {1}", s, s.GetStringLengths());
}
}
class Program
{
static string GetCurrentSourcePath([CallerFilePath] string str = null)
{
return str;
}
static string dllPath = Path.GetFullPath(
Path.Join(
GetCurrentSourcePath(),
"../nok-internal/target/debug/internal.dll"));
static void Main(string[] args)
{
NativeLibrary.SetDllImportResolver(
typeof(Program).Assembly,
(libraryName, assembly, searchPath) => NativeLibrary.Load(dllPath)
);
string str1 = "Hello, world!";
string str2 = "안녕, 세계!";
str1.PrintStringLengths();
str2.PrintStringLengths();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment