Created
December 24, 2021 00:12
-
-
Save rygo6/536168feb648f88f2cebdde7203e62a4 to your computer and use it in GitHub Desktop.
Marshall string from C# to wasmer.
This file contains 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.Collections.Generic; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
using System.Text; | |
using UnityEngine; | |
using WasmerSharp; | |
public class WASMTests : MonoBehaviour | |
{ | |
private Memory _memory; | |
private void Start() | |
{ | |
RunWASMTest(); | |
} | |
private void RunWASMTest() | |
{ | |
Import printFunc = new Import("index", "printExtern", new ImportFunction((Action<InstanceContext, int, int>) Print)); | |
Import getPlatformFunc = new Import("index", "getPlatformExtern", new ImportFunction((Func<InstanceContext, int>) GetPlatform)); | |
_memory = Memory.Create(minPages: 256, maxPages: 256); | |
Import memoryImport = new Import("env", "memory", _memory); | |
Import global = new Import("env", "__memory_base", new Global(1024, false)); | |
byte[] wasm = File.ReadAllBytes("AssemblyScript/untouched.wasm"); | |
Instance instance = new Instance(wasm, printFunc, getPlatformFunc, memoryImport, global); | |
object[] ret = instance.Call("hello_world"); | |
if (ret == null) | |
Debug.Log($"error calling method {instance.LastError}"); | |
else | |
Debug.Log("hello_world returned: " + ret); | |
} | |
private int GetPlatform(InstanceContext ctx) | |
{ | |
int offset = 0; | |
WasmString version = new WasmString($"Unity {Application.platform} {Application.unityVersion}"); | |
Marshal.StructureToPtr(version, ctx.GetMemory(0).Data, true); | |
return offset; | |
} | |
private void Print(InstanceContext ctx, int ptrOffset, int len) | |
{ | |
IntPtr memoryBase = ctx.GetMemory(0).Data; | |
// PrintMemory(ctx.GetMemory(0)); | |
string str = Marshal.PtrToStringUni(memoryBase + ptrOffset, len); | |
Debug.Log($"WASM Print: {str}"); | |
} | |
private unsafe void PrintMemory(Memory memory) | |
{ | |
Debug.Log($"Print Memory {memory.DataLength} {memory.PageLength}"); | |
byte* memBytePtr = (byte*) memory.Data.ToPointer(); | |
UnmanagedMemoryStream readStream = new UnmanagedMemoryStream(memBytePtr, 50, 50, FileAccess.Read); | |
byte[] outMessage = new byte[50]; | |
readStream.Read(outMessage, 0, 50); | |
StringBuilder sb = new StringBuilder(); | |
for (int i = 0; i < 50; i++) | |
{ | |
sb.AppendLine(outMessage[i].ToString()); | |
} | |
Debug.Log(sb.ToString()); | |
} | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1), Serializable] | |
public class WasmString | |
{ | |
// Const is not serialized to struct, but needs to be Const to use in MarshalAs Attribute. | |
public const int MaxCapacity = 64; | |
public readonly int Length; | |
public readonly int Capacity; | |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MaxCapacity)] | |
public readonly string Buffer; | |
public WasmString(string buffer) | |
{ | |
Buffer = buffer; | |
Length = Encoding.Unicode.GetByteCount(buffer); | |
Capacity = MaxCapacity; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment