Need help with Vector parameter when invoking C dll from C#

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?UHVjY2E=?=

    Need help with Vector parameter when invoking C dll from C#

    The function that I'm trying to call through DLLImport has a parameter that
    has a C code's vector's Itrator to a structure. I Have marshalled the
    structure in C# but how do I do the C type vector's Iterator in C#? The
    problem is in the next line and the rest of the code is just additional
    information on what I'm doing. Thanks.
    CUnityDS.DE_ERR ORS errcode = CUnityDS.LibWra p.EncodeAsnUser (ref blob,
    userContextData );


    //In & out parameter for data structure for meetingBlob decoded data
    [StructLayout(La youtKind.Sequen tial, CharSet = CharSet.Unicode )]
    public class CUserContextDat a
    {
    public int bWinLogOn = 0;
    public int bUnifiedID = 0;

    [MarshalAs(Unman agedType.ByValT Str, SizeConst =
    MAX_ADSPATH_CHA RS)]
    public String shell = null;
    [MarshalAs(Unman agedType.ByValT Str, SizeConst =
    MAX_ADSPATH_CHA RS)]
    public String homeDir = null;
    [MarshalAs(Unman agedType.ByValT Str, SizeConst =
    MAX_ADSPATH_CHA RS)]
    public String primaryGroupSID = null;
    [MarshalAs(Unman agedType.ByValT Str, SizeConst =
    MAX_ADSPATH_CHA RS)]
    public String LoginName = null;

    public int symarkUID = 0; //Unified User ID
    public int IID = 0; //Independant ID
    public int Revision = 0;
    }

    public class LibWrap
    {
    //import the dll that decodes the user meetingBlob
    [DllImport("Unit yDecodeAsnUser. dll", CharSet = CharSet.Unicode )]
    public static extern DE_ERRORS DecodeAsnUser(r ef Blob blob,
    [In, Out]CUserContextDat a m);

    [DllImport("Unit yDecodeAsnUser. dll", CharSet = CharSet.Unicode )]
    public static extern DE_ERRORS DecodeAsnGroup( ref Blob blob,
    [In, Out]CGroupContextDa ta m);

    [DllImport("Unit yDecodeAsnUser. dll", CharSet = CharSet.Unicode )]
    public static extern DE_ERRORS EncodeAsnUser(r ef Blob blob,
    [In, Out]CUserContextDat a m);

    CUnityDS.CUserC ontextData userContextData = new CUnityDS.CUserC ontextData();
    //put data into struc userContextData
    CUnityDS.DE_ERR ORS errcode = CUnityDS.LibWra p.EncodeAsnUser (ref blob,
    userContextData );
    deNewContextObj ect.Properties["meetingBlo b"].Add((object)bl ob);//got memory
    corruption error here



    int nBytes = Marshal.SizeOf( typeof(CUnityDS .Blob));
    IntPtr ptr = Marshal.AllocHG lobal(nBytes);

    // create an instance of the Blob structure
    CUnityDS.Blob blob = new CUnityDS.Blob() ;

    // copy and pin the structure to that location
    Marshal.Structu reToPtr(blob, ptr, true);

    // Pass it by reference
    // OK, now it's time to "reconsitut e" the structure
    blob = (CUnityDS.Blob) Marshal.PtrToSt ructure(ptr, typeof(CUnityDS .Blob));

    //-------- This is the C code for the import method of the dll
    extern "C" DE_ERRORS __declspec(dlle xport)EncodeAsn User(Blob** ppBlob,
    vector <CUserContextDa ta>::iterator userDataIter)
    {
    _bstr_t temp;
    AsnData* pAsn;
    //int boolInt;
    std::wstring wsUID;


    if ( ( pAsn = AsnAlloc( NULL ) ) == NULL )
    {
    DbgLog( DL_ERROR, "Unable to allocate ASN.1 buffer" );
    return DE_MEMORY_ALLOC ATION_FAILURE;
    }
    if ( !AsnPushTag(pAs n, (ASN_TAG$APPLIC ATION_START) ) )
    goto failed;

    if (!AsnWriteInteg er( pAsn, REVISION))
    goto failed;

    if(userDataIter->bUnifiedID)//use UID
    {
    if (!AsnWriteInteg er( pAsn, True) )
    goto failed;
    }
    else //use indep ID
    {
    if (!AsnWriteInteg er( pAsn, False) )
    goto failed;
    }
    if(userDataIter->IID == NULL)
    {
    if ( !AsnWriteGenera lString( pAsn, EMPTY_STRING))
    goto failed;
    }
    else
    {
    _bstr_t bstrtUID = L"0"; //initilize the bstr
    _itow(userDataI ter->IID, bstrtUID, 10);

    if ( !AsnWriteGenera lString( pAsn, bstrtUID.operat or const char *()))
    goto failed;
    }

    //WinUser name
    if(userDataIter->bWinLogOn)
    {
    if (!AsnWriteInteg er( pAsn, True) )
    goto failed;

    }
    else//use indep User Name
    {
    if (!AsnWriteInteg er( pAsn, False) )
    goto failed;
    }

    //Geco
    if ( !AsnWriteGenera lString( pAsn, EMPTY_STRING))
    goto failed;

    //Shell
    temp = userDataIter->shell.c_str( );
    if ( !AsnWriteGenera lString( pAsn, temp.operator const char *()))
    goto failed;

    //Home Driectory
    temp = userDataIter->homeDir.c_str( );
    if ( !AsnWriteGenera lString( pAsn, temp.operator const char *()))
    goto failed;

    //Primary Group SID
    temp = userDataIter->primaryGroupSI D.c_str();
    if (!AsnWriteGener alString( pAsn, temp.operator const char *()))
    goto failed;

    if ( !AsnPopTag( pAsn ) )
    goto failed;
    *ppBlob = AsnExtractData( pAsn );
    AsnFree( pAsn );
    return DE_SUCCESS;

    failed:
    DbgLog(DL_ERROR , "Failed to encode ASN.1 message packet" );
    AsnFree( pAsn );
    return DE_ENCODE_MESSA GE_PACKET_FAILU RE;
    }

  • Willy Denoyette [MVP]

    #2
    Re: Need help with Vector parameter when invoking C dll from C#

    "Pucca" <Pucca@discussi ons.microsoft.c omwrote in message
    news:8686DCD1-F569-415A-A7D7-D8DC600A1B54@mi crosoft.com...
    The function that I'm trying to call through DLLImport has a parameter
    that
    has a C code's vector's Itrator to a structure. I Have marshalled the
    structure in C# but how do I do the C type vector's Iterator in C#? The
    problem is in the next line and the rest of the code is just additional
    information on what I'm doing. Thanks.
    CUnityDS.DE_ERR ORS errcode = CUnityDS.LibWra p.EncodeAsnUser (ref blob,
    userContextData );
    >
    >
    //In & out parameter for data structure for meetingBlob decoded
    data
    [StructLayout(La youtKind.Sequen tial, CharSet = CharSet.Unicode )]
    public class CUserContextDat a
    {
    public int bWinLogOn = 0;
    public int bUnifiedID = 0;
    >
    [MarshalAs(Unman agedType.ByValT Str, SizeConst =
    MAX_ADSPATH_CHA RS)]
    public String shell = null;
    [MarshalAs(Unman agedType.ByValT Str, SizeConst =
    MAX_ADSPATH_CHA RS)]
    public String homeDir = null;
    [MarshalAs(Unman agedType.ByValT Str, SizeConst =
    MAX_ADSPATH_CHA RS)]
    public String primaryGroupSID = null;
    [MarshalAs(Unman agedType.ByValT Str, SizeConst =
    MAX_ADSPATH_CHA RS)]
    public String LoginName = null;
    >
    public int symarkUID = 0; //Unified User ID
    public int IID = 0; //Independant ID
    public int Revision = 0;
    }
    >
    public class LibWrap
    {
    //import the dll that decodes the user meetingBlob
    [DllImport("Unit yDecodeAsnUser. dll", CharSet =
    CharSet.Unicode )]
    public static extern DE_ERRORS DecodeAsnUser(r ef Blob blob,
    [In, Out]CUserContextDat a m);
    >
    [DllImport("Unit yDecodeAsnUser. dll", CharSet =
    CharSet.Unicode )]
    public static extern DE_ERRORS DecodeAsnGroup( ref Blob blob,
    [In, Out]CGroupContextDa ta m);
    >
    [DllImport("Unit yDecodeAsnUser. dll", CharSet =
    CharSet.Unicode )]
    public static extern DE_ERRORS EncodeAsnUser(r ef Blob blob,
    [In, Out]CUserContextDat a m);
    >
    CUnityDS.CUserC ontextData userContextData = new
    CUnityDS.CUserC ontextData();
    //put data into struc userContextData
    CUnityDS.DE_ERR ORS errcode = CUnityDS.LibWra p.EncodeAsnUser (ref blob,
    userContextData );
    deNewContextObj ect.Properties["meetingBlo b"].Add((object)bl ob);//got
    memory
    corruption error here
    >
    >
    >
    int nBytes = Marshal.SizeOf( typeof(CUnityDS .Blob));
    IntPtr ptr = Marshal.AllocHG lobal(nBytes);
    >
    // create an instance of the Blob structure
    CUnityDS.Blob blob = new CUnityDS.Blob() ;
    >
    // copy and pin the structure to that location
    Marshal.Structu reToPtr(blob, ptr, true);
    >
    // Pass it by reference
    // OK, now it's time to "reconsitut e" the structure
    blob = (CUnityDS.Blob) Marshal.PtrToSt ructure(ptr, typeof(CUnityDS .Blob));
    >
    //-------- This is the C code for the import method of the dll
    extern "C" DE_ERRORS __declspec(dlle xport)EncodeAsn User(Blob** ppBlob,
    vector <CUserContextDa ta>::iterator userDataIter)
    {
    _bstr_t temp;
    AsnData* pAsn;
    //int boolInt;
    std::wstring wsUID;
    >
    >
    if ( ( pAsn = AsnAlloc( NULL ) ) == NULL )
    {
    DbgLog( DL_ERROR, "Unable to allocate ASN.1 buffer" );
    return DE_MEMORY_ALLOC ATION_FAILURE;
    }
    if ( !AsnPushTag(pAs n, (ASN_TAG$APPLIC ATION_START) ) )
    goto failed;
    >
    if (!AsnWriteInteg er( pAsn, REVISION))
    goto failed;
    >
    if(userDataIter->bUnifiedID)//use UID
    {
    if (!AsnWriteInteg er( pAsn, True) )
    goto failed;
    }
    else //use indep ID
    {
    if (!AsnWriteInteg er( pAsn, False) )
    goto failed;
    }
    if(userDataIter->IID == NULL)
    {
    if ( !AsnWriteGenera lString( pAsn, EMPTY_STRING))
    goto failed;
    }
    else
    {
    _bstr_t bstrtUID = L"0"; //initilize the bstr
    _itow(userDataI ter->IID, bstrtUID, 10);
    >
    if ( !AsnWriteGenera lString( pAsn, bstrtUID.operat or const char *()))
    goto failed;
    }
    >
    //WinUser name
    if(userDataIter->bWinLogOn)
    {
    if (!AsnWriteInteg er( pAsn, True) )
    goto failed;
    >
    }
    else//use indep User Name
    {
    if (!AsnWriteInteg er( pAsn, False) )
    goto failed;
    }
    >
    //Geco
    if ( !AsnWriteGenera lString( pAsn, EMPTY_STRING))
    goto failed;
    >
    //Shell
    temp = userDataIter->shell.c_str( );
    if ( !AsnWriteGenera lString( pAsn, temp.operator const char *()))
    goto failed;
    >
    //Home Driectory
    temp = userDataIter->homeDir.c_str( );
    if ( !AsnWriteGenera lString( pAsn, temp.operator const char *()))
    goto failed;
    >
    //Primary Group SID
    temp = userDataIter->primaryGroupSI D.c_str();
    if (!AsnWriteGener alString( pAsn, temp.operator const char *()))
    goto failed;
    >
    if ( !AsnPopTag( pAsn ) )
    goto failed;
    *ppBlob = AsnExtractData( pAsn );
    AsnFree( pAsn );
    return DE_SUCCESS;
    >
    failed:
    DbgLog(DL_ERROR , "Failed to encode ASN.1 message packet" );
    AsnFree( pAsn );
    return DE_ENCODE_MESSA GE_PACKET_FAILU RE;
    }
    >


    Not sure what you are trying to achieve here, you are passing a structure to
    a function who's expecting a stl::vector iterator (according it's function
    signature), this can never work, but there is more, you aren't using this
    parameter as iterator in the C++ code, so this will never compile.

    Willy.

    Comment

    • =?Utf-8?B?UHVjY2E=?=

      #3
      Re: Need help with Vector parameter when invoking C dll from C#

      Hi Willy,
      You're correct about this will not compile in C# correctly. I need help in
      figuring out how to use and call this C++ function properly with the correct
      paramenter type. The C++ function is
      extern "C" DE_ERRORS __declspec(dlle xport)EncodeAsn User(Blob** ppBlob,
      vector <CUserContextDa ta>::iterator userDataIter)

      I have the structure CUserContextDat a declare correctly in C# already. But
      how do I use C# code to call this fucntion? I think the Blob** is declared
      correctly but how do I declare a vector::iterato r for the structure
      CUserContextDat a as a parameter in C# to call this function? Thank you.
      --
      Thanks.


      "Willy Denoyette [MVP]" wrote:
      "Pucca" <Pucca@discussi ons.microsoft.c omwrote in message
      news:8686DCD1-F569-415A-A7D7-D8DC600A1B54@mi crosoft.com...
      The function that I'm trying to call through DLLImport has a parameter
      that
      has a C code's vector's Itrator to a structure. I Have marshalled the
      structure in C# but how do I do the C type vector's Iterator in C#? The
      problem is in the next line and the rest of the code is just additional
      information on what I'm doing. Thanks.
      CUnityDS.DE_ERR ORS errcode = CUnityDS.LibWra p.EncodeAsnUser (ref blob,
      userContextData );


      //In & out parameter for data structure for meetingBlob decoded
      data
      [StructLayout(La youtKind.Sequen tial, CharSet = CharSet.Unicode )]
      public class CUserContextDat a
      {
      public int bWinLogOn = 0;
      public int bUnifiedID = 0;

      [MarshalAs(Unman agedType.ByValT Str, SizeConst =
      MAX_ADSPATH_CHA RS)]
      public String shell = null;
      [MarshalAs(Unman agedType.ByValT Str, SizeConst =
      MAX_ADSPATH_CHA RS)]
      public String homeDir = null;
      [MarshalAs(Unman agedType.ByValT Str, SizeConst =
      MAX_ADSPATH_CHA RS)]
      public String primaryGroupSID = null;
      [MarshalAs(Unman agedType.ByValT Str, SizeConst =
      MAX_ADSPATH_CHA RS)]
      public String LoginName = null;

      public int symarkUID = 0; //Unified User ID
      public int IID = 0; //Independant ID
      public int Revision = 0;
      }

      public class LibWrap
      {
      //import the dll that decodes the user meetingBlob
      [DllImport("Unit yDecodeAsnUser. dll", CharSet =
      CharSet.Unicode )]
      public static extern DE_ERRORS DecodeAsnUser(r ef Blob blob,
      [In, Out]CUserContextDat a m);

      [DllImport("Unit yDecodeAsnUser. dll", CharSet =
      CharSet.Unicode )]
      public static extern DE_ERRORS DecodeAsnGroup( ref Blob blob,
      [In, Out]CGroupContextDa ta m);

      [DllImport("Unit yDecodeAsnUser. dll", CharSet =
      CharSet.Unicode )]
      public static extern DE_ERRORS EncodeAsnUser(r ef Blob blob,
      [In, Out]CUserContextDat a m);

      CUnityDS.CUserC ontextData userContextData = new
      CUnityDS.CUserC ontextData();
      //put data into struc userContextData
      CUnityDS.DE_ERR ORS errcode = CUnityDS.LibWra p.EncodeAsnUser (ref blob,
      userContextData );
      deNewContextObj ect.Properties["meetingBlo b"].Add((object)bl ob);//got
      memory
      corruption error here



      int nBytes = Marshal.SizeOf( typeof(CUnityDS .Blob));
      IntPtr ptr = Marshal.AllocHG lobal(nBytes);

      // create an instance of the Blob structure
      CUnityDS.Blob blob = new CUnityDS.Blob() ;

      // copy and pin the structure to that location
      Marshal.Structu reToPtr(blob, ptr, true);

      // Pass it by reference
      // OK, now it's time to "reconsitut e" the structure
      blob = (CUnityDS.Blob) Marshal.PtrToSt ructure(ptr, typeof(CUnityDS .Blob));

      //-------- This is the C code for the import method of the dll
      extern "C" DE_ERRORS __declspec(dlle xport)EncodeAsn User(Blob** ppBlob,
      vector <CUserContextDa ta>::iterator userDataIter)
      {
      _bstr_t temp;
      AsnData* pAsn;
      //int boolInt;
      std::wstring wsUID;


      if ( ( pAsn = AsnAlloc( NULL ) ) == NULL )
      {
      DbgLog( DL_ERROR, "Unable to allocate ASN.1 buffer" );
      return DE_MEMORY_ALLOC ATION_FAILURE;
      }
      if ( !AsnPushTag(pAs n, (ASN_TAG$APPLIC ATION_START) ) )
      goto failed;

      if (!AsnWriteInteg er( pAsn, REVISION))
      goto failed;

      if(userDataIter->bUnifiedID)//use UID
      {
      if (!AsnWriteInteg er( pAsn, True) )
      goto failed;
      }
      else //use indep ID
      {
      if (!AsnWriteInteg er( pAsn, False) )
      goto failed;
      }
      if(userDataIter->IID == NULL)
      {
      if ( !AsnWriteGenera lString( pAsn, EMPTY_STRING))
      goto failed;
      }
      else
      {
      _bstr_t bstrtUID = L"0"; //initilize the bstr
      _itow(userDataI ter->IID, bstrtUID, 10);

      if ( !AsnWriteGenera lString( pAsn, bstrtUID.operat or const char *()))
      goto failed;
      }

      //WinUser name
      if(userDataIter->bWinLogOn)
      {
      if (!AsnWriteInteg er( pAsn, True) )
      goto failed;

      }
      else//use indep User Name
      {
      if (!AsnWriteInteg er( pAsn, False) )
      goto failed;
      }

      //Geco
      if ( !AsnWriteGenera lString( pAsn, EMPTY_STRING))
      goto failed;

      //Shell
      temp = userDataIter->shell.c_str( );
      if ( !AsnWriteGenera lString( pAsn, temp.operator const char *()))
      goto failed;

      //Home Driectory
      temp = userDataIter->homeDir.c_str( );
      if ( !AsnWriteGenera lString( pAsn, temp.operator const char *()))
      goto failed;

      //Primary Group SID
      temp = userDataIter->primaryGroupSI D.c_str();
      if (!AsnWriteGener alString( pAsn, temp.operator const char *()))
      goto failed;

      if ( !AsnPopTag( pAsn ) )
      goto failed;
      *ppBlob = AsnExtractData( pAsn );
      AsnFree( pAsn );
      return DE_SUCCESS;

      failed:
      DbgLog(DL_ERROR , "Failed to encode ASN.1 message packet" );
      AsnFree( pAsn );
      return DE_ENCODE_MESSA GE_PACKET_FAILU RE;
      }
      >
      >
      >
      Not sure what you are trying to achieve here, you are passing a structure to
      a function who's expecting a stl::vector iterator (according it's function
      signature), this can never work, but there is more, you aren't using this
      parameter as iterator in the C++ code, so this will never compile.
      >
      Willy.
      >
      >

      Comment

      • Willy Denoyette [MVP]

        #4
        Re: Need help with Vector parameter when invoking C dll from C#

        "Pucca" <Pucca@discussi ons.microsoft.c omwrote in message
        news:42DED808-4BE8-4E06-94E5-EA8297734083@mi crosoft.com...
        Hi Willy,
        You're correct about this will not compile in C# correctly. I need help
        in
        figuring out how to use and call this C++ function properly with the
        correct
        paramenter type. The C++ function is
        extern "C" DE_ERRORS __declspec(dlle xport)EncodeAsn User(Blob** ppBlob,
        vector <CUserContextDa ta>::iterator userDataIter)
        >
        I have the structure CUserContextDat a declare correctly in C# already.
        But
        how do I use C# code to call this fucntion? I think the Blob** is
        declared
        correctly but how do I declare a vector::iterato r for the structure
        CUserContextDat a as a parameter in C# to call this function? Thank you.
        --

        You can't call this function from C#, you can only pass an iterator from
        C++. What you could do is implement a function in a C++ wrapper that takes
        an array of type CUserContextDat a and convert this into a vector of type
        CUserContextDat a, then you need to declare a vector iterator for this vector
        and pass the iterator to the EncodeAsnUser function.

        Willy.

        Comment

        • =?Utf-8?B?UHVjY2E=?=

          #5
          Re: Need help with Vector parameter when invoking C dll from C#

          Thanks Willy. I think maybe I'll try working on a new C code function
          similar to the one with vector except that I would only need to pass in the
          structure CUserContextDat a. This might be easier for me than the wrapper.
          From C# I'm only encoding one user structure at a time and really don't need
          the vector stuff. Thank you very much.
          --
          Thanks.


          "Willy Denoyette [MVP]" wrote:
          "Pucca" <Pucca@discussi ons.microsoft.c omwrote in message
          news:42DED808-4BE8-4E06-94E5-EA8297734083@mi crosoft.com...
          Hi Willy,
          You're correct about this will not compile in C# correctly. I need help
          in
          figuring out how to use and call this C++ function properly with the
          correct
          paramenter type. The C++ function is
          extern "C" DE_ERRORS __declspec(dlle xport)EncodeAsn User(Blob** ppBlob,
          vector <CUserContextDa ta>::iterator userDataIter)

          I have the structure CUserContextDat a declare correctly in C# already.
          But
          how do I use C# code to call this fucntion? I think the Blob** is
          declared
          correctly but how do I declare a vector::iterato r for the structure
          CUserContextDat a as a parameter in C# to call this function? Thank you.
          --
          >
          >
          You can't call this function from C#, you can only pass an iterator from
          C++. What you could do is implement a function in a C++ wrapper that takes
          an array of type CUserContextDat a and convert this into a vector of type
          CUserContextDat a, then you need to declare a vector iterator for this vector
          and pass the iterator to the EncodeAsnUser function.
          >
          Willy.
          >
          >

          Comment

          Working...