Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Consider using the explicit conversion to byte[] array. This way you explicitly specify where the struct is.</p> <p>In C you have:</p> <pre><code>extern "C" void FooBarCreate(FooBar* Data); extern "C" void FooBarUse(FooBar* Data) </code></pre> <p>In C# you write:</p> <pre><code> [DllImport("SomeFile.dll")] public static extern void FooBarCreate_DLL([In,Out] byte[] BufForFOOBAR); [DllImport("SomeFile.dll")] public static extern void FooBarUSE_DLL([In,Out] byte[] BufForFOOBAR); /// Call DLL with managed struct public static Int32 FooBarUse_Managed(ManagedFooBar Value) { byte[] ValueBuffer = StructureToByteArray(Value); return FooBarUse_DLL(ValueBuffer); } /// Get value from native DLL to managed struct public static void FooBarCreate_Managed(ref ManagedFooBar Value) { byte[] ValueBuffer = new byte[Marshal.SizeOf(Value)]; FooBarCreate_DLL(ValueBuffer); object TmpObj = new ManagedFooBar(); ByteArrayToStructure(ValueBuffer, ref TmpObj); Value = (ManagedFooBar)TmpObj; } </code></pre> <p>The native function is called directly by C#.</p> <p>The StructToByteArray and ByteArrayToStruct function are right here:</p> <pre><code>using System.Runtime.InteropServices; using System.Runtime.Serialization; public static byte[] StructureToByteArray(object obj) { int len = Marshal.SizeOf(obj); byte[] arr = new byte[len]; IntPtr ptr = Marshal.AllocHGlobal(len); Marshal.StructureToPtr(obj, ptr, true); Marshal.Copy(ptr, arr, 0, len); Marshal.FreeHGlobal(ptr); return arr; } public static void ByteArrayToStructure(byte[] bytearray, ref object obj) { int len = Marshal.SizeOf(obj); IntPtr i = Marshal.AllocHGlobal(len); Marshal.Copy(bytearray, 0, i, len); obj = Marshal.PtrToStructure(i, obj.GetType()); Marshal.FreeHGlobal(i); } </code></pre> <p>One last thing, the FooBarManaged (in C#):</p> <pre><code>[Serializable] /// Sequential - make sure C does uses the same struct member alignment [StructLayout(LayoutKind.Sequential, Pack=1)] public struct FooBarManaged { // Ususal POD field public Int32 ExpID; // Constant-sized string [MarshalAs(UnmanagedType.ByValArray, SizeConst=128)] public byte[] FileName; } </code></pre> <p>There's not much to tell about this code. I've used a simple autogenerator for this kind of marshalling to use the native sqlite3 backend as a data storage. Thus the need to marshal a lot of structs to and from C.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload