Reputation: 139
I have a .NET Core console app that calls some functions from C++ library. The function I'm trying to call simpty taken in some settings
and outputs the result into 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);
This all works well on Windows but does not work on Linux. When I print the settings on a C++ side (from process_input
), I get completely different values in int and double properties, and a Segmentation Fault when try to access char* property.
I also tried to call this library from C++ code (Windows and Linux) and it works as expected. As I understand, this is a marshaling problem, but I can't pinpoint it myself. I'm a C# developer and don't have much experience with C++ or PInvoke or Linux.
I work with Windows 10 (x64) and Ubuntu 16.04 (x64).
Upvotes: 1
Views: 1631
Reputation: 139
As David Heffernan suggested in the comments, I added an explicit ref
keyword and it worked.
Here's my function's signature before:
public static extern bool ProcessInput(Settings settings, out Result result);
and after:
public static extern bool ProcessInput(ref Settings settings, out Result result);
Upvotes: 2