封送 return 结构的本机方法

Marshaling native method that return struct

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

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 类型中的 return 结构,但我不知道是否可以使用封送处理指令使我的结构可 blittable。 有什么办法可以做到这一点,或者我的代码有其他问题吗? 如果没有办法,我需要更改 API 并将 return 类型作为输出参数。

谢谢。

您可以使用固定大小的缓冲区使其可 blittable:

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

请注意,我使用 sbyte 作为数组元素类型。这是一个 8 位类型,与同样是 8 位类型的 unamanged char 类型相匹配。您在 C# 中使用了 char,这是一个 16 位类型。

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