I apologize for the brief deep-end on CLR internals...

On Mon, Sep 2, 2013 at 7:50 AM, Bennie Kloosteman <[email protected]>wrote:

>  I use this marshal all the time for interop of C arrays embeded in
>> structs  so i dont think its a pointer to an array ..
>>
>
In managed space it is a pointer to an array.

"Marshalling" is the process of copying data in and out of managed space.
What you are doing is telling the marshaller what the output copy format
looks like in unmanaged space. You are not changing the layout of the
memory in managed-space. The only way to embed an array within a managed
struct/class is to use unsafe-fixed.

This is shap's complaint, as there is nothing "unsafe" about using a
fixed-size array. As long as it's only for structs (with no subtyping) and
the size is known at compile-time, i don't even see anything tricky about
it. If it's allowed in classes, or runtime sizes are allowed, then it needs
indirection, either via parametric instantiation or some vtable-esq
indirection scheme.

---

If you want to prove this to yourself, instead of marshalling the struct,
share the unmanaged struct pointer between C# and C, then after you share
just the pointer (without marshalling the struct), try to change the
contents of your fixedBuffer on the C# side, and verify it on the C side.
You will see that it is unchanged, because it's not the same data.

If you use fully unsafe structs and fixed (not fixed marshalling), then it
is *literally* formatting the data in memory exactly like C, and you can
share the pointer once and have both worlds touching the same underlying
data. This is important for things like cache-efficiency optimization, and
also for shared-memory communication.

The managed code of the test would look something like:

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct data {
  int header;
  unsafe fixed char fixedBuffer[128];
}

// marshall the pointer out of C land, using something like...

[DllImport("mytest.dll")]
unsafe data* getStructPtr(); // init the buffer to "from-CC"

[DllImport("mytest.dll")]
void printFixedBuffer();

// then test it:

unsafe void main() {
      unsafe data* myPtr = getStructPtr();
      printFixedBuffer(); // prints "from-CC"
      data->fixedBuffer[6] = '#';   // no marshall, we are directly
touching the data
      printFixedBuffer(); // prints "from-C#"

      // if you do this same test with your "marshalling" version,
      // you will see it print "from-cc" both times.
}
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to