-
-
Save zah/fe8f5956684abee6bec9 to your computer and use it in GitHub Desktop.
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) | |
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
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 !
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