Last active
July 11, 2020 15:53
-
-
Save paxbun/e7e4acb3851ea362bad5280f29e65aa3 to your computer and use it in GitHub Desktop.
C# and Rust interop example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [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"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #[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), | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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