CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Nov 2005
    Posts
    50

    COM returns array of bytes

    Hi everybody

    I have a com object that returns an array of bytes:
    Code:
    public Byte[] ReadCodePage(bool IsCode, UInt32 Address, Int32 NumberOfBytes)
    From the client, I have VS 2003. How do I call this function. I am aware of SAFEARRAY, and CComSafeArray, but I am having no success using it.
    Can somebody send me a short post on how to do this, and access the bytes after the function call? All help is much appreciated.

    -rlien

  2. #2
    Join Date
    Oct 2003
    Location
    Minnesota
    Posts
    175

    Re: COM returns array of bytes

    If you are trying to call something via a COM interface, you would probably want an HRESULT as the return value and pass a byte array pointer to the function all. I am not clear on all the details, but a basic COM call might look something like this:

    Code:
    (server)
    
    STDMETHODIMP AddTwoNumbers(int x, int y, int *result)
    {
       result = x + y;
       return S_OK;
    }
    Code:
    (client)
    
    int x = 2;
    int y = 3;
    int result = 0;
    HRESULT hr = AddTwoNumbers(x, y, &result);
    If you want to get into safe arrays, I can show examples on that, but I think you need to adjust your call to COM first (unless I am missunderstanding the question).

  3. #3
    Join Date
    Nov 2005
    Posts
    50

    Re: COM returns array of bytes

    I failed to mention that this component is written in C#, 2005 express.

  4. #4
    Join Date
    Oct 2003
    Location
    Minnesota
    Posts
    175

    Re: COM returns array of bytes

    I'm confused - did you create a dll in C# that you hope to include in your client and make calls to it? If so, then you just need to reference it within your project.

    Or

    Do you have a C++ dll that you want to use C# to make a call to?

    In either case you need to make a reference to the COM object in the C# project.

  5. #5
    Join Date
    Nov 2005
    Posts
    50

    Re: COM returns array of bytes

    The dll is written in c#, 2005 express edition.
    My client is written in vc++, visuall studio 2003.

    I my client header I have

    Code:
    #import ".\Mydll.tlb" raw_interfaces_only
    My initiall assumption was that I make the call

    Code:
    SAFEARRAY SA;
    .
    .
    .
    spSomeSmartPointer->ReadCodePage(bvarIsCodePage, nAddress, nBytesToRead, &SA);

  6. #6
    Join Date
    Nov 2005
    Posts
    50

    Re: COM returns array of bytes

    Furthermore, my problem as I see it is to set up the safearray, and then access the byte array that the dll returned.

  7. #7
    Join Date
    Oct 2003
    Location
    Minnesota
    Posts
    175

    Re: COM returns array of bytes

    So what you are saying is that you have a managed dll (C#) which is being called by unmanaged C++. I believe this will help you:

    Code:
    // Managed Code (C#) includes
    #pragma warning (disable: 4278)
    #import <mscorlib.tlb> raw_interfaces_only
    
    #if defined (USINGPROJECTSYSTEM)
    #import ".\Mydll.tlb" no_namespace named_guids
    #else
    #import ".\Mydll.tlb" no_namespace named_guids
    #endif
    
    // Project settings for using managed and unmanaged code
    //1) Go To ---Project Property->Configuration Property --->c/c++ --->/clr
    //2) Go To ---Project Property->Configuration Property --->Code Generation-->Basic Runtime Checks-->Default
    //3) Go To ---Project Property->Configuration Property --->Code Generation-->Enable Minimal Rebuild--> N
    //4) Go To ---Project Property->Configuration Property --->c/c++ -->General-->Debug Information Format-->Program Database (/Zi)
    //5) Go To ---Project Property->Configuration Property --->Code Generation-->Runtime Library--><inherit from project defaults>
    Now, to look at your function call:

    public Byte[] ReadCodePage(bool IsCode, UInt32 Address, Int32 NumberOfBytes)

    I think this will return as a VARIANT, which is a type of SafeArray. You can actually use the call SafeArrayGetElement(array.parray, &index, &item) with index being a long and item being a BSTR (or whatever you are getting back).

  8. #8
    Join Date
    Nov 2005
    Posts
    50

    Re: COM returns array of bytes

    Hi drm,

    I do know it returns a safearray. My initial problem was how to use this safe array.

    Code:
    SAFEARRAY *pSA;
    SAFEARRAYBOUND aDim[1];    // one dimensional array
    aDim[0].lLbound= 0;
    aDim[0].cElements= 32;
    char * pActualData= NULL;
    
    pSA= SafeArrayCreate(VT_UI1,1,aDim);
    
    spIOCDTPtr->ReadCodePage(bvarIsCodePage, nAddress, nBytesToRead, &pSA);
    My initial intension has been something along the lines as above. Due to my limited knowledge on safearrays I am not able to set it up correctly or retrieve the bytes from it after the call.

    roar
    Last edited by rlien; May 25th, 2007 at 03:38 PM.

  9. #9
    Join Date
    Oct 2003
    Location
    Minnesota
    Posts
    175

    Re: COM returns array of bytes

    To create the SafeArray you can do the following:
    Code:
    // Create the SAFEARRAY
    USES_CONVERSION;
    SAFEARRAY *pSA;
    SAFEARRAYBOUND dimensions[1];
    dimensions[0].lLbound = 0;
    dimensions[0].cElements = numItemNames;
    pSA = SafeArrayCreate(VT_VARIANT, 1, dimensions);
    if (pSA == NULL)
    {
    	return E_FAIL; // unable to create the safearray
    }
    To insert items into a SafeArray you can use the following:
    Code:
    long index = 0;
    string itemName = "foo";
    
    _variant_t itemNameVariant;
    itemNameVariant = A2W(itemName.c_str());
    HRESULT hr = SafeArrayPutElement(pSA, &index, &itemNameVariant);
    if (FAILED(hr))
    {
    	SafeArrayDestroy(pSA);
    	return E_FAIL;
    }
    To get items out of the SafeArray you would do the following:
    Code:
    BSTR item = NULL;
    long index = 0;
    SafeArrayGetElement(pSA.parray, &index, &item);
    I think how you are calling it is incorrect, but I don't know the code. You might want to try this instead:
    Code:
    int nBytesToRead= 0;
    int index = 0;
    BSTR item = NULL;
    
    VARIANT foo = spIOCDTPtr->ReadCodePage(bvarIsCodePage, nAddress, nBytesToRead);
    
    SafeArrayGetElement(foo.parray, &index, &item);
    By doing the above, you are stating that an object is being returned and within that object you want to access the array within it. You can write a loop around SafeArrayGetElement which will be the value of your index.

  10. #10
    Join Date
    Nov 2005
    Posts
    50

    Resolved Re: COM returns array of bytes

    Jepp drm,
    You nailed it. If any is facing the same issue here it is:

    Code:
    // read a page
        INT32 nBytesToRead = 4;
    
        // Create the SAFEARRAY
        USES_CONVERSION;
        SAFEARRAY *pSA;
        SAFEARRAYBOUND dimensions[1];
        dimensions[0].lLbound = 0;
        dimensions[0].cElements = nBytesToRead;
        pSA = SafeArrayCreate(VT_VARIANT, 1, dimensions);
        if (pSA == NULL)
        {
    	    return 0; // unable to create the safearray
        }
    
        VARIANT_BOOL bvarIsCodePage = true;
        INT32 nAddress = 0;
       
        pIOCDLPPtr->ReadCodePage(bvarIsCodePage, nAddress, nBytesToRead, &pSA);
    
        BYTE item = 0;
    
        for(long i = 0; i < nBytesToRead; i++)
            SafeArrayGetElement(pSA, &i, &item);

    and the c# dll

    Code:
    public Byte [] ReadCodePage(bool IsCode, UInt32 Address, Int32 NumberOfBytes)
    {
    
                Byte[] bTest= new Byte[4];
    
                bTest[0] = 0x55;
                bTest[1] = 0x56;
                bTest[2] = 0x57;
                bTest[3] = 0x58;
    
                return bTest;
    }
    Go Cylones (and Vikings)! Happy friday

    roar

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured