none
C vs C# pb interop (passing array Struct contenning char[256]) RRS feed

  • Question

  • Hi,
    Sorry for my poor english

    I have a C method with an array of struct ST_TRACEINTERVAL
    and I want to request this method by C#. But it's not working Why ?
    if  I replace on C char text[256] by char *text and use malloc in fucntion and change in C# public String text_ by public IntPtr text_;
    using string nom = Marshal.PtrToStringAnsi(lstTracesInterval[i].text_); all it's working fine

    thanks in advances for you answering.

     

     




    see bellow my implementation :
    #pragma pack(1)
    typedef struct

            double from;
            double to;
           char   text[256]; 
    } ST_TRACEINTERVAL;
    #pragma pack()
    BOOL DllExportStd T_GetActiveComponentsOfTrace(char *pszTraceName, double from, double to,ST_TRACEINTERVAL *_intervals,DWORD* nbInterval)
    {
      ST_TRACEINTERVAL *interval;

      *nbInterval = 4;
      
      //_intervals=(ST_TRACEINTERVAL *)GlobalAlloc(GMEM_FIXED,(*nbInterval)*sizeof(ST_TRACEINTERVAL));

      for (int i=0;i<*nbInterval;i++){
         interval=&_intervals[i];//(_intervals+(i*sizeof(ST_TRACEINTERVAL)));
      interval->from=GetGeonextTime();
      interval->to=i;
      //interval->text=new char[256];
      sprintf(interval->text,"%s.%d",pszTraceName,i);
      //lstrcpy(interval->text,"ABCD");
      }
      return TRUE;
    }


    [

    StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct ST_TRACEINTERVAL{
    [MarshalAs(UnmanagedType.R8)]
    public double from_;
    [MarshalAs(UnmanagedType.R8)]
    public double to_;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public String text_;
    };

     

    bool state = GeonextDataAccessWrapper.T_GetActiveComponentsOfTrace(new StringBuilder(pszMnemo), 0, double.MaxValue,ref lstTracesInterval[0], ref count);

    Thursday, June 25, 2009 4:35 PM

Answers

  • I dunno, but "ref lstTracesInterval[0]" does not look like a very good idea.  You haven't posted the P/Invoke declaration, make sure it is

      [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=3)] ST_TRACEINTERVAL[]

    And make sure you pre-allocate the array to contain at least as many elements as the C/C++ code is ever going to write.  Getting that wrong will destroy the heap.

    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Thursday, July 2, 2009 12:31 PM
    Thursday, June 25, 2009 5:45 PM
    Moderator

All replies

  • I dunno, but "ref lstTracesInterval[0]" does not look like a very good idea.  You haven't posted the P/Invoke declaration, make sure it is

      [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=3)] ST_TRACEINTERVAL[]

    And make sure you pre-allocate the array to contain at least as many elements as the C/C++ code is ever going to write.  Getting that wrong will destroy the heap.

    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Thursday, July 2, 2009 12:31 PM
    Thursday, June 25, 2009 5:45 PM
    Moderator
  •  

    thanks for your reply
    my the P/Invoke declaration :
    internal
    static extern bool T_GetActiveComponentsOfTrace([MarshalAs(UnmanagedType.LPStr)] StringBuilder pszMnemo, double from, double to, [In, Out, MarshalAs(UnmanagedType.Struct)] ref ST_TRACEINTERVAL pNewInterval, ref int cnt);

    tanks in advance

    Friday, June 26, 2009 5:54 AM
  • Yeah, you can't pass an array like that.

    Hans Passant.
    Friday, June 26, 2009 9:34 AM
    Moderator