封送返回struct

时间:2019-03-04 14:26:37

标签: c# pinvoke marshalling

我正在尝试封送由本机代码返回的结构,但得到System.Runtime.InteropServices.MarshalDirectiveException 不是在其他帖子中已经回答过的输出参数,而是返回类型。

C ++代码:

typedef struct
{
    bool success;
    ErrorCode error_code;
    char error_path[1025];
} Result;

DLLEXPORT Result GetResult();

ErrorCode是一个枚举,
相当于C#:

[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();

我知道C# p/invoke should be blitable类型的返回构造,但是我不知道是否可以使用Marshaling指令使结构可蓝变。 有什么办法可以做,还是我的代码有其他问题? 如果没有办法,我需要更改API并将返回类型作为输出参数。

谢谢。

1 个答案:

答案 0 :(得分:1)

您可以使用固定大小的缓冲区使它可变蓝:

[StructLayout(LayoutKind.Sequential)]
public unsafe struct Result
{
    public byte success;
    public ErrorCode error_code;
    public fixed sbyte error_path[1025];
}

请注意,我已经使用sbyte作为数组元素类型。这是一种8位类型,与无用的char类型相匹配,后者也是8位类型。您在C#(16位类型)中使用了char

您可能需要将固定大小的缓冲区转换为字符串,但是确切的操作方法取决于您使用的编码。但是,您可以通过网络搜索找到关于该主题的大量文章(将固定大小的缓冲区转换为字符串)。