Linux 上的 .NET Core - 元帅结构
.NET Core on Linux - Marshal structures
我有一个 .NET Core 控制台应用程序,它从 C++ 库中调用一些函数。我试图调用 simpty 的函数接受了一些 settings
并将结果输出到 result
。
C++:
struct settings
{
char* input_path;
char* first_file;
char* second_file;
char* mask;
char* log_path;
int count_accepted;
double confidence;
char* device;
};
struct result
{
int count;
foo* foos;
bool is_preprocessed;
double duration;
};
bool process_input(const settings& settings, result* result);
C#:
[StructLayout(LayoutKind.Sequential)]
public struct Settings
{
[MarshalAs(UnmanagedType.LPStr)]
public string input_path;
[MarshalAs(UnmanagedType.LPStr)]
public string first_file;
[MarshalAs(UnmanagedType.LPStr)]
public string second_file;
[MarshalAs(UnmanagedType.LPStr)]
public string mask;
[MarshalAs(UnmanagedType.LPStr)]
public string log_path;
[MarshalAs(UnmanagedType.I4)]
public int count_accepted;
[MarshalAs(UnmanagedType.R8)]
public double confidence;
[MarshalAs(UnmanagedType.LPStr)]
public string device;
}
[StructLayout(LayoutKind.Sequential)]
public struct Result
{
[MarshalAs(UnmanagedType.I4)]
public int count;
[MarshalAs(UnmanagedType.SysInt)]
public IntPtr foos;
[MarshalAs(UnmanagedType.I1)]
public bool is_preprocessed;
[MarshalAs(UnmanagedType.R8)]
public double duration;
}
[DllImport("myLib", EntryPoint = "process_input", CallingConvention = CallingConvention.Cdecl)]
[return:MarshalAs(UnmanagedType.I1)]
public static extern bool ProcessInput(Settings settings, out Result result);
这一切在 Windows 上运行良好,但在 Linux 上不起作用。当我在 C++ 端(来自 process_input
)打印设置时,我在 int 和 double 属性中得到完全不同的值,并且在尝试访问 char* 属性.
时出现分段错误
我还尝试从 C++ 代码(Windows 和 Linux)调用这个库,它按预期工作。据我了解,这是一个编组问题,但我自己无法查明。我是一名 C# 开发人员,对 C++ 或 PInvoke 或 Linux 没有太多经验。
我使用 Windows 10 (x64) 和 Ubuntu 16.04 (x64)。
正如评论中的 David Heffernan ,我添加了一个显式的 ref
关键字并且有效。
这是我之前函数的签名:
public static extern bool ProcessInput(Settings settings, out Result result);
及之后:
public static extern bool ProcessInput(ref Settings settings, out Result result);
我有一个 .NET Core 控制台应用程序,它从 C++ 库中调用一些函数。我试图调用 simpty 的函数接受了一些 settings
并将结果输出到 result
。
C++:
struct settings
{
char* input_path;
char* first_file;
char* second_file;
char* mask;
char* log_path;
int count_accepted;
double confidence;
char* device;
};
struct result
{
int count;
foo* foos;
bool is_preprocessed;
double duration;
};
bool process_input(const settings& settings, result* result);
C#:
[StructLayout(LayoutKind.Sequential)]
public struct Settings
{
[MarshalAs(UnmanagedType.LPStr)]
public string input_path;
[MarshalAs(UnmanagedType.LPStr)]
public string first_file;
[MarshalAs(UnmanagedType.LPStr)]
public string second_file;
[MarshalAs(UnmanagedType.LPStr)]
public string mask;
[MarshalAs(UnmanagedType.LPStr)]
public string log_path;
[MarshalAs(UnmanagedType.I4)]
public int count_accepted;
[MarshalAs(UnmanagedType.R8)]
public double confidence;
[MarshalAs(UnmanagedType.LPStr)]
public string device;
}
[StructLayout(LayoutKind.Sequential)]
public struct Result
{
[MarshalAs(UnmanagedType.I4)]
public int count;
[MarshalAs(UnmanagedType.SysInt)]
public IntPtr foos;
[MarshalAs(UnmanagedType.I1)]
public bool is_preprocessed;
[MarshalAs(UnmanagedType.R8)]
public double duration;
}
[DllImport("myLib", EntryPoint = "process_input", CallingConvention = CallingConvention.Cdecl)]
[return:MarshalAs(UnmanagedType.I1)]
public static extern bool ProcessInput(Settings settings, out Result result);
这一切在 Windows 上运行良好,但在 Linux 上不起作用。当我在 C++ 端(来自 process_input
)打印设置时,我在 int 和 double 属性中得到完全不同的值,并且在尝试访问 char* 属性.
我还尝试从 C++ 代码(Windows 和 Linux)调用这个库,它按预期工作。据我了解,这是一个编组问题,但我自己无法查明。我是一名 C# 开发人员,对 C++ 或 PInvoke 或 Linux 没有太多经验。
我使用 Windows 10 (x64) 和 Ubuntu 16.04 (x64)。
正如评论中的 David Heffernan ref
关键字并且有效。
这是我之前函数的签名:
public static extern bool ProcessInput(Settings settings, out Result result);
及之后:
public static extern bool ProcessInput(ref Settings settings, out Result result);