Need Help with COM object HEC-RAS

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • FariborzNouri
    New Member
    • Feb 2009
    • 3

    Need Help with COM object HEC-RAS

    Need help with HEC-RAS
    Hello
    I am trying to run a COM application known as HEC-RAS from an unmanaged C++ program in Visual Studio. Classes have been added to the project by adding new MFC classes from a TypeLib. CoInitialize() has been called and interface has been created successfully. One particular method in one of the classes CHECRASControll er has the following signature in C++.
    Code:
    BOOL Compute_CurrentPlan(long * nmsg, SAFEARRAY * * msg); 
    Using Object Browser this function is 
    Function Compute_CurrentPlan(nmsg As Long, msg() As String) As Boolean.
    In another project we used a mixture of VB and C++ and successfully called the above function, I found that the return parameter msg() is an array of 3 strings.

    In C++ I wrote
    Code:
       long pl;
       
       SAFEARRAYBOUND rgsabound[1];
       rgsabound[0].lLbound = 1;     // lower bound for indexing, in VB it would have been 1
       rgsabound[0].cElements = 3;   // from vb runs i found that 3 strings will be returned
       //SAFEARRAY *psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
       SAFEARRAY *psa = SafeArrayCreate(VT_BSTR, 1, rgsabound);
       psa->fFeatures = FADF_BSTR | FADF_AUTO; //  | FADF_FIXEDSIZE;
    I called the function as
    hec.Compute_Cur rentPlan(&pl, &psa);

    This causes an internal error, I also tried creating the SAFEARRAY with VT_NULL or VT_EMPTY as the element types by
    Code:
       /* trying to see whether I can create it as VT_EMPTY or VT_NULL 
       SAFEARRAYBOUND rgsabound[1];
       rgsabound[0].lLbound = 1;     // lower bound for indexing, in VB it would have been 1
       rgsabound[0].cElements = 1;   // from vb runs i found that 3 strings will be returned
       SAFEARRAY *psa;
       psa = SafeArrayCreateEx(VT_EMPTY, 1, rgsabound, NULL);  //  VT_NULL
       */
    Again no success. I will appreciate any help as I don’t have experience with COM objects.
    Thanks in advance
    Last edited by pbmods; Feb 13 '09, 12:48 AM. Reason: Added CODE tags.
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    It's been long time since I looked at COM but you might try:

    Code:
    rgsabound[0].lLbound = 0;    
    rgsabound[0].cElements = 3;
    I believe that is for a SAFEARRAY of 3 elements with a starting index of 0. Arrays in C/C++ start indexing at 0.

    Let me know what happens.

    Comment

    • FariborzNouri
      New Member
      • Feb 2009
      • 3

      #3
      Unfortunately that didn't work either. The source code of the function in the header file was
      Code:
         BOOL Compute_CurrentPlan(long * nmsg, SAFEARRAY **msg)
         {
            BOOL result;
            static BYTE parms[] = VTS_PI4 VTS_UNKNOWN ;
            InvokeHelper(0x6003000b, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms, nmsg, msg);
            return result;
         }
      I noticed that parms[] has VTS_UNKNOWN so I went back and changed the safe array creation to
      Code:
         SAFEARRAYBOUND rgsabound[1];
         rgsabound[0].lLbound = 0;     // lower bound for indexing, in VB it would have been 1
         rgsabound[0].cElements =3;   // from vb runs i found that 3 strings will be returned
         SAFEARRAY *psa = SafeArrayCreate(VT_UNKNOWN, 1, rgsabound);
      That didn't work either. I am completely out of ideas now !!!

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        Did you actually put elements in your SAFEARRAY?

        I took your code and created a SAFEARRAY of BSTR and then created three BSTR and then put those BSTRs in the SAFEARRAY.

        I can see them in the SAFEARRAY using my debugger.

        Code:
        SAFEARRAYBOUND rgsabound[1]; 
           rgsabound[0].lLbound = 1;     // lower bound for indexing, in VB it would have been 1 
           rgsabound[0].cElements = 3;   // from vb runs i found that 3 strings will be returned 
           //SAFEARRAY *psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound); 
           SAFEARRAY *psa = SafeArrayCreate(VT_BSTR, 1, rgsabound); 
           psa->fFeatures = FADF_BSTR | FADF_AUTO; //  | FADF_FIXEDSIZE;  
        
           BSTR x = SysAllocString(L"Hello");
           BSTR y = SysAllocString(L"this is a ");
           BSTR z = SysAllocString(L"COM test");
        
           //goes to ILbound =1, c.Elements = 1;
           rgsabound[0].cElements = 1; 
           HRESULT hr =  SafeArrayPutElement(psa, (long*)rgsabound, x);
           //goes to ILbound =1, c.Elements = 2;
            rgsabound[0].cElements = 2; 
           hr = SafeArrayPutElement(psa, (long*)rgsabound, y);
            //goes to ILbound =1, c.Elements = 3;
            rgsabound[0].cElements = 3; 
           hr = SafeArrayPutElement(psa, (long*)rgsabound, z);
        I do not show the SysFreeString calls.

        Comment

        Working...