I'm trying to marshal a struct that is returned by my native code but I get System.Runtime.InteropServices.MarshalDirectiveException
It is not a output argument that already answered in other posts, it is return type.
C++ code:
typedef struct
{
bool success;
ErrorCode error_code;
char error_path[1025];
} Result;
DLLEXPORT Result GetResult();
ErrorCode
is an enum,
C# equivalent:
[StructLayout(LayoutKind.Sequential)]
public struct Result
{
public byte success;
public ErrorCode error_code;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 1025)]
public char[] error_path;
}
[DllImport("shared", EntryPoint = "GetReult", CallingConvention = CallingConvention.Cdecl)]
public extern static Result GetResult();
I know the return stucts in C# p/invoke should be blitable type but I don't know if I can make my struct blittable using the Marshaling directives or not. Is there any way do do that or is something other is wrong with my code? If there is no way I need to change my API and make the return type as output argument.
Thanks.
You can make it blittable by using a fixed size buffer:
[StructLayout(LayoutKind.Sequential)]
public unsafe struct Result
{
public byte success;
public ErrorCode error_code;
public fixed sbyte error_path[1025];
}
Note that I have used sbyte
for the array element type. That's an 8 bit type that matches the unamanged char
type which is also an 8 bit type. You used char
in your C# which is a 16 bit type.
You may need to convert the fixed size buffer to a string, but exactly how to do that depends upon the encoding that you used. However, there are plenty of articles on that topic (converting fixed size buffer to string) that you can find by web search.