Search code examples
c#variablesinteropdeclaration

conditional variable types in C# interop depending on OS and Architecture


C# Interop question.

i have a C++ library that uses a struct:

struct CPPSTRUCT
{
    long v1;
    short v2;
    long v3;
}

In C#, I have a corresponding structure:

[StructLayout(LayoutKind.Sequential)]
public struct MANAGEDSTRUCT
{ 
    public int v1;
    public short v2;
    public int v3;
}

It works as long as C++ library is built for Windows x64, however, it breaks when same library is built for Linux x64. The reason for it breaking, is because C++ length of long is 4 bytes in Win x64 but is 8 bytes in Linux x64: changing int types in MANAGEDSTRUCT to long types fixes the issue for linux x64, but breaks it for windows x64. Another issue is that when setting/getting the values for v1 and v3 in MANAGEDSTRUCT may become conditional as well.

I am looking for the best C# appropriate way to conditionally declare variable types/Marshall it depending on OS/Architecture, so that application consuming the C++ library can target multiple platforms without having to worry about types, and being able to set values in MANAGEDSSTRUCT by the client.

Thank you!


Solution

  • Not sure it will work, but you can try global types alias as following (pseudocode)

    #if Windows
        global using NativeLong = System.Int32; //int
    #elseif Linux
        global using NativeLong = System.Int64; //long
    #endif
    
    [StructLayout(LayoutKind.Sequential)]
    public struct MANAGEDSTRUCT
    { 
        public NativeLong v1;
        public short v2;
        public NativeLong v3;
    }
    

    Then you can use this NativeLong in all the codebase.

    Specs for global type alias are here

    P.S. Please review the comments under the question (especially by @Flydog57 and @ipodtouch0218 - looks like it is better approach shown there)