i have struct , code:
[structlayout(layoutkind.sequential, pack = 8)] private class xvid_image_t { [marshalas(unmanagedtype.byvalarray, sizeconst = 4)] public int[] stride; // [marshalas(unmanagedtype.byvalarray, sizeconst = 4)] // public intptr[] plane; } public int decore() { xvid_image_t mystruct = new xvid_image_t(); mystruct.stride = new int[4]; // can commented out - same result gchandle.alloc(mystruct, gchandletype.pinned); // ... }
when try run argumentexception
saying:
object contains non-primitive or non-blittable data
after reading this msdn page saying
the following complex types blittable types:
one-dimensional arrays of blittable types, such array of integers. however, type contains variable array of blittable types not blittable.
formatted value types contain blittable types (and classes if marshaled formatted types). more information formatted value types, see default marshaling value types.
i don't understand doing wrong. don't want use marshal
, understand too.
so want know:
- why?
- how can resolve this?
- will solution provide work commented line in struct?
i using .net 4.5 solution .net 2.0 needed.
object contains non-primitive or non-blittable data
that's exception message get. focusing on "non-blittable" part of message, that's not problem. "non-primitive" part that's issue. array non-primitive data type.
the clr trying keep out of trouble here. pin object still have problem, array won't pinned. object isn't pinned when has fields need pinned well.
and have bigger problem unmanagedtype.byvalarray, requires structural conversion. in other words, layout need different layout of managed class object. pinvoke marshaller can make conversion.
you can want without using pinvoke marshaller using fixed size buffers, using fixed keyword. requires using unsafe keyword. make this:
[structlayout(layoutkind.sequential)] unsafe private struct xvid_image_t { public fixed int stride[4]; }
note have change declaration struct type. value type, no longer need use gchandle pin value when make local variable. make sure whatever unmanaged code takes structure value, reference, not store pointer struct. that's going blow badly , utterly undiagnosably. unsafe keyword appropriate here. if store pointer have byte bullet , use marshal.allochglobal() , marshal.structuretoptr() ensure pointer stays valid while unmanaged code using it.
Comments
Post a Comment