I'm writing a C++/CLI layer to handle some interop.
The native API populates a complex structure involving fixed arrays, unions, anonymous structures, etc:
typedef struct DECLSPEC_ALIGN(16) _FOO {
union {
BAR Bar;
struct {
POP Array[8];
DWORD More;
};
};
} FOO, *PFOO;
I'm trying to translate this data structure to more "sane" .NET class, for consumption by C#. The problem is, I can't use this legacy structure, and gcnew
my new class in the same function:
Foo^ Test::GetFoo(HANDLE h)
{
FOO foo; // Necessarily unmanaged
if (!::GetFoo(h, &foo))
throw gcnew Exception("GetFoo failed");
Foo^ result = gcnew Foo(); // Necessarily managed
// populate result
return result;
}
Doing so gives the error:
Error 2 error C3821: 'void Test::GetFoo(HANDLE)': managed type or function cannot be used in an unmanaged function
If a native structure and a gcnew
cannot exist in the same function, how can one ever hope to (even manually) marshall data between the two?
Many Q/A here involve wrapping unmanaged classes, which seems to be irrelevant here.
Aligned data types not supported in managed code
That's the real error message, unfortunately it does not show up in the Error List window. You can only see it in the Output window. Something to keep in mind when compiler error messages look bizarre.
And yes, it is accurate, managed code doesn't run with the stack alignment guarantees that are needed to get this structure aligned. 32-bit code runs with an alignment of 4, 64-bit code can provide 8. Not good enough to get 16. Nothing the compiler can do about it either, the usual stack pointer manipulations are not available in IL, that screws up the metadata that the jitter generates that tells the garbage collector where the look for object references when it walks the stack.
So, no can do, you cannot make it a local variable. You've got choices, the most straight-forward way is to allocate it:
#include <malloc.h>
....
FOO* value = (FOO*)_aligned_malloc(sizeof(FOO), __alignof(FOO));
try {
// etc...
}
finally {
_aligned_free(value);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With