封送 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 位类型。
您可能需要将固定大小的缓冲区转换为字符串,但具体操作方法取决于您使用的编码。但是,您可以通过网络搜索找到很多关于该主题(将固定大小的缓冲区转换为字符串)的文章。
我正在尝试编组由我的本机代码 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 位类型。
您可能需要将固定大小的缓冲区转换为字符串,但具体操作方法取决于您使用的编码。但是,您可以通过网络搜索找到很多关于该主题(将固定大小的缓冲区转换为字符串)的文章。