Convert a C struct to C# (an interop problem)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • ~toki

    Convert a C struct to C# (an interop problem)

    I'm triyng to use this function
    int result = NativeMethods.m idiOutGetDevCap s( -1, ref pSI,
    (uint)Marshal.S izeOf(pSI) );

    Docs say that pSI is a struct (below)
    [c++]
    typedef struct {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    CHAR szPname[MAXPNAMELEN]; // Here's the problem
    WORD wTechnology;
    WORD wVoices;
    WORD wNotes;
    WORD wChannelMask;
    DWORD dwSupport;
    } MIDIOUTCAPS;


    This is my code in c#
    [C#]
    public struct MIDIOUTCAPS {
    public int wMid;
    public int wPid;
    public long vDriverVersion;
    public char[] szPname; // Here's the problem
    public int wTechnology;
    public int wVoices;
    public int wNotes;
    public int wChannelMask;
    public long dwSupport;
    }

    MIDIOUTCAPS pSI = new MIDIOUTCAPS();
    pSI.szPname = new char[32];
    int result = NativeMethods.m idiOutGetDevCap s( -1, ref pSI,
    (uint)Marshal.S izeOf(pSI) );

    This code, give me a nullreference error (the callback stop in the
    Kernel32.dll)

    If i change "public char[] szPname; X public char szPname;" works fine
    (don't retrieve the szPname) (I rename too, of course, pSI.szPname = new
    char[32];)

    "CHAR szPname[MAXPNAMELEN];" is a null-terminated string

    Some idea?


  • ~toki

    #2
    Re: Convert a C struct to C# (an interop problem)

    A small question should be "How can i dimension a char 'in line' (in a
    structure)"


    "~toki" <pedorro77.hotm ail.com> escribió en el mensaje
    news:uJfmKbz9DH A.2324@tk2msftn gp13.phx.gbl...[color=blue]
    > I'm triyng to use this function
    > int result = NativeMethods.m idiOutGetDevCap s( -1, ref pSI,
    > (uint)Marshal.S izeOf(pSI) );
    >
    > Docs say that pSI is a struct (below)
    > [c++]
    > typedef struct {
    > WORD wMid;
    > WORD wPid;
    > MMVERSION vDriverVersion;
    > CHAR szPname[MAXPNAMELEN]; // Here's the problem
    > WORD wTechnology;
    > WORD wVoices;
    > WORD wNotes;
    > WORD wChannelMask;
    > DWORD dwSupport;
    > } MIDIOUTCAPS;
    >
    >
    > This is my code in c#
    > [C#]
    > public struct MIDIOUTCAPS {
    > public int wMid;
    > public int wPid;
    > public long vDriverVersion;
    > public char[] szPname; // Here's the problem
    > public int wTechnology;
    > public int wVoices;
    > public int wNotes;
    > public int wChannelMask;
    > public long dwSupport;
    > }
    >
    > MIDIOUTCAPS pSI = new MIDIOUTCAPS();
    > pSI.szPname = new char[32];
    > int result = NativeMethods.m idiOutGetDevCap s( -1, ref pSI,
    > (uint)Marshal.S izeOf(pSI) );
    >
    > This code, give me a nullreference error (the callback stop in the
    > Kernel32.dll)
    >
    > If i change "public char[] szPname; X public char szPname;" works fine
    > (don't retrieve the szPname) (I rename too, of course, pSI.szPname = new
    > char[32];)
    >
    > "CHAR szPname[MAXPNAMELEN];" is a null-terminated string
    >
    > Some idea?
    >
    >[/color]


    Comment

    • ~toki

      #3
      Re: Convert a C struct to C# (an interop problem)

      Hi ~toki, it's simple

      [C#]
      public struct MIDIOUTCAPS {
      public int wMid;
      public int wPid;
      public long vDriverVersion;
      [MarshalAs(Unman agedType.ByValA rray, SizeConst=32)]
      public char[] szPname;
      public int wTechnology;
      public int wVoices;
      public int wNotes;
      public int wChannelMask;
      public long dwSupport;
      }

      Regards,
      ~toki
      :>)

      "~toki" <pedorro77.hotm ail.com> escribió en el mensaje
      news:%2339A5vz9 DHA.548@TK2MSFT NGP11.phx.gbl.. .[color=blue]
      > A small question should be "How can i dimension a char 'in line' (in a
      > structure)"
      >
      >
      > "~toki" <pedorro77.hotm ail.com> escribió en el mensaje
      > news:uJfmKbz9DH A.2324@tk2msftn gp13.phx.gbl...[color=green]
      > > I'm triyng to use this function
      > > int result = NativeMethods.m idiOutGetDevCap s( -1, ref pSI,
      > > (uint)Marshal.S izeOf(pSI) );
      > >
      > > Docs say that pSI is a struct (below)
      > > [c++]
      > > typedef struct {
      > > WORD wMid;
      > > WORD wPid;
      > > MMVERSION vDriverVersion;
      > > CHAR szPname[MAXPNAMELEN]; // Here's the problem
      > > WORD wTechnology;
      > > WORD wVoices;
      > > WORD wNotes;
      > > WORD wChannelMask;
      > > DWORD dwSupport;
      > > } MIDIOUTCAPS;
      > >
      > >
      > > This is my code in c#
      > > [C#]
      > > public struct MIDIOUTCAPS {
      > > public int wMid;
      > > public int wPid;
      > > public long vDriverVersion;
      > > public char[] szPname; // Here's the problem
      > > public int wTechnology;
      > > public int wVoices;
      > > public int wNotes;
      > > public int wChannelMask;
      > > public long dwSupport;
      > > }
      > >
      > > MIDIOUTCAPS pSI = new MIDIOUTCAPS();
      > > pSI.szPname = new char[32];
      > > int result = NativeMethods.m idiOutGetDevCap s( -1, ref pSI,
      > > (uint)Marshal.S izeOf(pSI) );
      > >
      > > This code, give me a nullreference error (the callback stop in the
      > > Kernel32.dll)
      > >
      > > If i change "public char[] szPname; X public char szPname;" works fine
      > > (don't retrieve the szPname) (I rename too, of course, pSI.szPname = new
      > > char[32];)
      > >
      > > "CHAR szPname[MAXPNAMELEN];" is a null-terminated string
      > >
      > > Some idea?
      > >
      > >[/color]
      >
      >[/color]


      Comment

      • Alison

        #4
        RE: Convert a C struct to C# (an interop problem)

        Hi, Toki

        I met the problem before, but slightly different from yours.
        Looks like the definition of character array inside of struct MIDIOUTCAPS is supposed to specify an array size. You just declared a char array. This will not work in C#.


        Comment

        • Chris R

          #5
          Re: Convert a C struct to C# (an interop problem)

          Try this layout.
          A WORD is 16 bit (short), not 32(int). A DWORD is 32 bit(ing), not 64
          (long).
          Make sure to check MMVERSION and use long for 64 bit or int for 32 bit.

          [color=blue]
          > [C#][/color]
          [StructLayout( LayoutKind.Sequ ential, CharSet=CharSet .Ansi )]
          public struct MIDIOUTCAPS {
          public short wMid;
          public short wPid;
          public long vDriverVersion; // is MMVERSION a 64 bit number?
          [MarshalAs( UnmanagedType.B yValTStr, SizeConst=32 )]
          public string szPname;
          public short wTechnology;
          public short wVoices;
          public short wNotes;
          public short wChannelMask;
          public int dwSupport;
          }

          Chris R.

          "~toki" <pedorro77.hotm ail.com> wrote in message
          news:uJfmKbz9DH A.2324@tk2msftn gp13.phx.gbl...[color=blue]
          > I'm triyng to use this function
          > int result = NativeMethods.m idiOutGetDevCap s( -1, ref pSI,
          > (uint)Marshal.S izeOf(pSI) );
          >
          > Docs say that pSI is a struct (below)
          > [c++]
          > typedef struct {
          > WORD wMid;
          > WORD wPid;
          > MMVERSION vDriverVersion;
          > CHAR szPname[MAXPNAMELEN]; // Here's the problem
          > WORD wTechnology;
          > WORD wVoices;
          > WORD wNotes;
          > WORD wChannelMask;
          > DWORD dwSupport;
          > } MIDIOUTCAPS;
          >
          >
          > This is my code in c#
          > [C#]
          > public struct MIDIOUTCAPS {
          > public int wMid;
          > public int wPid;
          > public long vDriverVersion;
          > public char[] szPname; // Here's the problem
          > public int wTechnology;
          > public int wVoices;
          > public int wNotes;
          > public int wChannelMask;
          > public long dwSupport;
          > }
          >
          > MIDIOUTCAPS pSI = new MIDIOUTCAPS();
          > pSI.szPname = new char[32];
          > int result = NativeMethods.m idiOutGetDevCap s( -1, ref pSI,
          > (uint)Marshal.S izeOf(pSI) );
          >
          > This code, give me a nullreference error (the callback stop in the
          > Kernel32.dll)
          >
          > If i change "public char[] szPname; X public char szPname;" works fine
          > (don't retrieve the szPname) (I rename too, of course, pSI.szPname = new
          > char[32];)
          >
          > "CHAR szPname[MAXPNAMELEN];" is a null-terminated string
          >
          > Some idea?
          >
          >[/color]


          Comment

          • ~toki

            #6
            Re: Convert a C struct to C# (an interop problem)

            I found the same solution that you post.
            It works now.
            But i go to check the long, int & shorts.
            Thanks,,


            "Chris R" <sothryn@hotmai l.com> escribió en el mensaje
            news:utq$AN09DH A.1496@TK2MSFTN GP09.phx.gbl...[color=blue]
            > Try this layout.
            > A WORD is 16 bit (short), not 32(int). A DWORD is 32 bit(ing), not 64
            > (long).
            > Make sure to check MMVERSION and use long for 64 bit or int for 32 bit.
            >
            >[color=green]
            > > [C#][/color]
            > [StructLayout( LayoutKind.Sequ ential, CharSet=CharSet .Ansi )]
            > public struct MIDIOUTCAPS {
            > public short wMid;
            > public short wPid;
            > public long vDriverVersion; // is MMVERSION a 64 bit number?
            > [MarshalAs( UnmanagedType.B yValTStr, SizeConst=32 )]
            > public string szPname;
            > public short wTechnology;
            > public short wVoices;
            > public short wNotes;
            > public short wChannelMask;
            > public int dwSupport;
            > }
            >
            > Chris R.
            >
            > "~toki" <pedorro77.hotm ail.com> wrote in message
            > news:uJfmKbz9DH A.2324@tk2msftn gp13.phx.gbl...[color=green]
            > > I'm triyng to use this function
            > > int result = NativeMethods.m idiOutGetDevCap s( -1, ref pSI,
            > > (uint)Marshal.S izeOf(pSI) );
            > >
            > > Docs say that pSI is a struct (below)
            > > [c++]
            > > typedef struct {
            > > WORD wMid;
            > > WORD wPid;
            > > MMVERSION vDriverVersion;
            > > CHAR szPname[MAXPNAMELEN]; // Here's the problem
            > > WORD wTechnology;
            > > WORD wVoices;
            > > WORD wNotes;
            > > WORD wChannelMask;
            > > DWORD dwSupport;
            > > } MIDIOUTCAPS;
            > >
            > >
            > > This is my code in c#
            > > [C#]
            > > public struct MIDIOUTCAPS {
            > > public int wMid;
            > > public int wPid;
            > > public long vDriverVersion;
            > > public char[] szPname; // Here's the problem
            > > public int wTechnology;
            > > public int wVoices;
            > > public int wNotes;
            > > public int wChannelMask;
            > > public long dwSupport;
            > > }
            > >
            > > MIDIOUTCAPS pSI = new MIDIOUTCAPS();
            > > pSI.szPname = new char[32];
            > > int result = NativeMethods.m idiOutGetDevCap s( -1, ref pSI,
            > > (uint)Marshal.S izeOf(pSI) );
            > >
            > > This code, give me a nullreference error (the callback stop in the
            > > Kernel32.dll)
            > >
            > > If i change "public char[] szPname; X public char szPname;" works fine
            > > (don't retrieve the szPname) (I rename too, of course, pSI.szPname = new
            > > char[32];)
            > >
            > > "CHAR szPname[MAXPNAMELEN];" is a null-terminated string
            > >
            > > Some idea?
            > >
            > >[/color]
            >
            >[/color]


            Comment

            • gbonnet
              New Member
              • May 2006
              • 1

              #7
              Hi,

              here is my code:

              public short wMid;
              public short wPid;
              public uint vDriverVersion;
              [MarshalAs(Unman agedType.ByValA rray, SizeConst=32)]
              public char[] szPname;
              public int dwFormats;
              public short wChannels;
              public short wReserved1;

              It works fine!
              Good luck with your project

              Bye

              Guillaume

              Comment

              Working...