-
-
Save rbanay/8bcc37ad5cb0b6497daf to your computer and use it in GitHub Desktop.
NimString in C#
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
# variant 2) convert the Nim string to a manually managed piece of memory | |
type | |
Exported = objec | |
len: int | |
data: ptr char # this has to be freed with Nim's `dealloc` proc | |
proc marshal(x: string): Exported = | |
result.len = x.len | |
result.data = create(char, x.len + 1) | |
copyMem(result.data, cstring(x), x.len + 1) | |
// but here i am complitly lost what do i use as the buffer: the Exported above? | |
proc GetPacksPtrNim(parSze: int, PackArrINOUT: var DataPackArr){.exportc,dynlib.} = | |
PackArrINOUT.newSeq(parSze) | |
var dummy:string ="abcdefghij" | |
for i, curDataPack in PackArrINOUT.mpairs: | |
# here i generate value by adding the iterator i to the buffer so i will know for sure it's new values on each element | |
curDataPack = DataPack(buffer:dummy & $i, intVal: uint32 i) | |
#and it's the simulation of putting any kind of unknown length string from a file or database... | |
#that is why i bother with the trailing char(i + int8'0') |
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
// variant 1) directly exposing the Nim string type to C# | |
... | |
[StructLayout(LayoutKind.Sequential)] | |
public struct NimString | |
{ | |
public uint Len; | |
public uint Capacity; | |
public LPStr Text; | |
} | |
... | |
[StructLayout(LayoutKind.Sequential)] | |
public struct TestC | |
{ | |
public uint Id; | |
public NimString Str; | |
} | |
// variant 2) converting strings to manually managed memory before passing them to C# | |
// my Version so far | |
[StructLayout(LayoutKind.Sequential)] | |
public struct NimString | |
{ | |
public uint Len; | |
public uint Capacity; | |
public char* Text; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct TestNimStr | |
{ | |
public uint Id; | |
public NimString Str; | |
} | |
//iterop Signature | |
[DllImport(@"G:\RobDev\Documents\Visual Studio 2010\Projects\CPP_Interaction\Nim\x64\testnimatom.dll", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | |
public static extern void GetPacksPtrNim(int size, TestNimStr** outPackArr); | |
//this is how i return from Nim | |
public static unsafe List<TestNimStr> PopulateLstPackCharNim(int ArrL) | |
{ | |
TestNimStr* PackUArrOut = null; | |
List<TestNimStr> RtPackLst = new List<TestNimStr>(ArrL); | |
GetPacksPtrNim(ArrL, &PackUArrOut); | |
TestNimStr* CurrentPack = PackUArrOut; | |
for (int i = 0; i < ArrL; i++, CurrentPack++) | |
{ | |
// here it was simple ..where Strval is IntPtr later i marahsll it... so it actually also two steps | |
//with the original DataPack-IntPtr member | |
RtPackLst.Add(new TestNimStr() { StrVal = CurrentPack->StrVal, IntVal = CurrentPack->IntVal }); | |
string accessedElementStr = Marshal.PtrToStringAnsi(RtPackLst.element(number).Strval); | |
// but how do i access here so there's actually no extra steps in your approach i realise while writing | |
RtPackLst.Add(new TestNimStr() { Str = CurrentPack->Str, Id = CurrentPack->IntVal }); | |
// Which is NimString struct | |
var testAccessStructAsString = RtPackLst.element(number).Str; | |
//so actually: as string ---v method likes it |------v (is a char*) | |
string buildTheString = new string(RtPackLst.element(number).Str.Text) | |
} | |
return RtPackLst; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
this was actually simple(C# side), i will now try to work on the complete implementation of your approach on the nim side