Skip to content

Instantly share code, notes, and snippets.

@zah
Last active October 22, 2017 12:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zah/fe8f5956684abee6bec9 to your computer and use it in GitHub Desktop.
Save zah/fe8f5956684abee6bec9 to your computer and use it in GitHub Desktop.
Importing Nim modules from C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace nim_sharp
{
[StructLayout(LayoutKind.Sequential)]
public unsafe struct NimSring
{
public Int32 Len;
public Int32 Capacity;
public char Text;
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct NimSeq
{
public Int32 Len;
public Int32 Capacity;
public byte Data;
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct NimType_ext
{
public Int32 x;
public Int32 y;
public NimSring* s;
}
public struct NimType
{
public int x;
public int y;
public string s;
}
class Program
{
[DllImport("nimlib.dll", CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern void populateArraySruct(int length, NimSeq** ArrayStructs);
public static unsafe List<NimType> getResultsFromNim(int ArrL)
{
List<NimType> convertedResults = new List<NimType>(ArrL);
NimSeq* nimResults = null;
populateArraySruct(ArrL, &nimResults);
NimType_ext* currentItem = (NimType_ext*) &(nimResults->Data);
for (int i = 0; i < ArrL; i++, currentItem++)
{
convertedResults.Add(new NimType() {x = currentItem->x, y = currentItem->y, s = new string(&(currentItem->s->Text))});
}
return convertedResults;
}
static void Main(string[] args)
{
var list = getResultsFromNim(10);
foreach (var elem in list) {
Console.WriteLine("x: {0}, y: {1}, s: {2}", elem.x, elem.y, elem.s);
}
}
}
}
# compile with nim c -app:lib nimlib.nim
# place next to the C# executable together with a compiled copy of nimrtl.dll
type
NimTypeSeq = seq[NimType]
NimType = object {.packed.}
x: int
y: int
s: string
proc populateArraySruct(outputLength: int, output: var NimTypeSeq) {.exportc,dynlib.} =
setupForeignThreadGc()
output.newSeq(outputLength)
for i in 0 .. <outputLength:
output[i] = NimType(x: i, y: i*2, s: $i)
@rbanay
Copy link

rbanay commented Nov 13, 2015

the only problem i have left as i mention in former post, as we only pass numeric char now it does work but encoding is wrong shows string as??? is this an issue or simple solution ? try concat $i as s= "abc" & $i

@zah
Copy link
Author

zah commented Nov 14, 2015

Nim strings are usually stored in UTF-8, although the language doesn't require that. In C#, the encoding is UCS-2 (UTF-16). Take a look at the following stackoverflow answer that features some conversion code:
http://stackoverflow.com/questions/10773440/conversion-in-net-native-utf-8-managed-string

@rbanay
Copy link

rbanay commented Nov 14, 2015

StringFromNativeUtf8 is the one i think, i will take a time to test both ways to see if that is the solution, as this has to be the one, i will report to you as soon as i find the time to play with it again, thanks i think that concludes the subject of the string passing from nim to c# which was not a simple task for me, as soon as i will confront this, and do some more tests i will be more familiar and it will be simpler from that point, i'll let you know. thanks a lot as ususall !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment