Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. COM
  4. TROUBLE Passing BYTE Array from Client to COM OUTPROC Server [modified]

TROUBLE Passing BYTE Array from Client to COM OUTPROC Server [modified]

Scheduled Pinned Locked Moved COM
questioncomsysadmindata-structures
25 Posts 2 Posters 8 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    K ARUN KUMAR
    wrote on last edited by
    #1

    Hi, I have an outproc server Executable which exposes an Interface IServicer. IServicer has a Method GetBytArray([in]BYTE* bytArray). This method has to get a Byte array from client and utilise the values of the array. When iam calling this Interface method from client by passing a byte array of size 10, at the server iam only able to access the first element of the array. i.e only first element of the array is marshalled from client to Server. This is happening only in the case of OUTPROC Servers. How can i access the entire BYTE array without utilising VARIANT or SAFEARRAY concepts?

    modified on Tuesday, May 18, 2010 1:00 AM

    S 1 Reply Last reply
    0
    • K K ARUN KUMAR

      Hi, I have an outproc server Executable which exposes an Interface IServicer. IServicer has a Method GetBytArray([in]BYTE* bytArray). This method has to get a Byte array from client and utilise the values of the array. When iam calling this Interface method from client by passing a byte array of size 10, at the server iam only able to access the first element of the array. i.e only first element of the array is marshalled from client to Server. This is happening only in the case of OUTPROC Servers. How can i access the entire BYTE array without utilising VARIANT or SAFEARRAY concepts?

      modified on Tuesday, May 18, 2010 1:00 AM

      S Offline
      S Offline
      Stephen Hewitt
      wrote on last edited by
      #2

      Where is the size_is[^] attribute (and others like length_is)? Given the client and server are in different address spaces clearly this information is required (COM isn't psychic).

      Steve

      K 1 Reply Last reply
      0
      • S Stephen Hewitt

        Where is the size_is[^] attribute (and others like length_is)? Given the client and server are in different address spaces clearly this information is required (COM isn't psychic).

        Steve

        K Offline
        K Offline
        K ARUN KUMAR
        wrote on last edited by
        #3

        Hi Steve, Thanks for the Info. I tried using Size_is option. Still nor working. Can you give me a working Client Server Code? Thanking you. Arun

        S 1 Reply Last reply
        0
        • K K ARUN KUMAR

          Hi Steve, Thanks for the Info. I tried using Size_is option. Still nor working. Can you give me a working Client Server Code? Thanking you. Arun

          S Offline
          S Offline
          Stephen Hewitt
          wrote on last edited by
          #4

          Did you register the proxy-stub? I'm betting no! Anyway I hacked this together: The client:

          #include "stdafx.h"

          #import "../Server/Debug/Server.tlb" no_namespace

          void DoIt()
          {
          IServicerPtr p;
          HRESULT hr = p.CreateInstance(__uuidof(Servicer));
          if (SUCCEEDED(hr))
          {
          BYTE data[] = {1, 2, 3, 4, 3, 2, 1};
          p->SetData(sizeof(data), data);
          }
          }

          int APIENTRY _tWinMain(HINSTANCE hInstance,
          HINSTANCE hPrevInstance,
          LPTSTR lpCmdLine,
          int nCmdShow)
          {
          CoInitialize(NULL);
          DoIt();
          CoUninitialize();

          return 0;
          

          }

          The server's IDL (extract).

          [
          object,
          uuid(3D71D2F1-E297-4B26-B2AC-32EA22EFC2B4),
          helpstring("IServicer Interface"),
          pointer_default(unique)
          ]
          interface IServicer : IUnknown{
          [helpstring("method SetData")] HRESULT SetData([in] ULONG size, [in, size_is(size)] BYTE * pData);
          };

          The server (extract):

          STDMETHODIMP CServicer::SetData(/*[in]*/ ULONG size, /*[in, size_is(size)]*/ BYTE * pData)
          {
          ostringstream oss;
          for (ULONG i=0; i<size; ++i)
          {
          oss << static_cast<int>(pData[i]) << " ";
          }

          MessageBoxA(NULL, oss.str().c\_str(), "Server", MB\_OK);
          
          return S\_OK;
          

          }

          Steve

          K 1 Reply Last reply
          0
          • S Stephen Hewitt

            Did you register the proxy-stub? I'm betting no! Anyway I hacked this together: The client:

            #include "stdafx.h"

            #import "../Server/Debug/Server.tlb" no_namespace

            void DoIt()
            {
            IServicerPtr p;
            HRESULT hr = p.CreateInstance(__uuidof(Servicer));
            if (SUCCEEDED(hr))
            {
            BYTE data[] = {1, 2, 3, 4, 3, 2, 1};
            p->SetData(sizeof(data), data);
            }
            }

            int APIENTRY _tWinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPTSTR lpCmdLine,
            int nCmdShow)
            {
            CoInitialize(NULL);
            DoIt();
            CoUninitialize();

            return 0;
            

            }

            The server's IDL (extract).

            [
            object,
            uuid(3D71D2F1-E297-4B26-B2AC-32EA22EFC2B4),
            helpstring("IServicer Interface"),
            pointer_default(unique)
            ]
            interface IServicer : IUnknown{
            [helpstring("method SetData")] HRESULT SetData([in] ULONG size, [in, size_is(size)] BYTE * pData);
            };

            The server (extract):

            STDMETHODIMP CServicer::SetData(/*[in]*/ ULONG size, /*[in, size_is(size)]*/ BYTE * pData)
            {
            ostringstream oss;
            for (ULONG i=0; i<size; ++i)
            {
            oss << static_cast<int>(pData[i]) << " ";
            }

            MessageBoxA(NULL, oss.str().c\_str(), "Server", MB\_OK);
            
            return S\_OK;
            

            }

            Steve

            K Offline
            K Offline
            K ARUN KUMAR
            wrote on last edited by
            #5

            Hi Steve, Thanks a lot for the code. How to register the Proxy-Stub of my Outproc dll or exe?

            S 1 Reply Last reply
            0
            • K K ARUN KUMAR

              Hi Steve, Thanks a lot for the code. How to register the Proxy-Stub of my Outproc dll or exe?

              S Offline
              S Offline
              Stephen Hewitt
              wrote on last edited by
              #6

              What development environment are you using? What frameworks (if any) are you using to build the COM servers?

              Steve

              K 1 Reply Last reply
              0
              • S Stephen Hewitt

                What development environment are you using? What frameworks (if any) are you using to build the COM servers?

                Steve

                K Offline
                K Offline
                K ARUN KUMAR
                wrote on last edited by
                #7

                Im using Visual Studio 2003. In that i have taken an ATL Project. Server type is: Service(exe) which exposes IServicer interface.

                S 1 Reply Last reply
                0
                • K K ARUN KUMAR

                  Im using Visual Studio 2003. In that i have taken an ATL Project. Server type is: Service(exe) which exposes IServicer interface.

                  S Offline
                  S Offline
                  Stephen Hewitt
                  wrote on last edited by
                  #8

                  I built mine with 2008. What projects are in the workspace? Is there a project to build the proxy-stub (name ends in "PS")?

                  Steve

                  K 1 Reply Last reply
                  0
                  • S Stephen Hewitt

                    I built mine with 2008. What projects are in the workspace? Is there a project to build the proxy-stub (name ends in "PS")?

                    Steve

                    K Offline
                    K Offline
                    K ARUN KUMAR
                    wrote on last edited by
                    #9

                    I have a Project named BytComp and BytCompPS in my workspace. I built the BytCompPS and found ByCompPS.dll and registered it using regsvr32 command. Now, i have added a new interface method as suggested by you but still im not able to access the entire array. :doh:

                    S 1 Reply Last reply
                    0
                    • K K ARUN KUMAR

                      I have a Project named BytComp and BytCompPS in my workspace. I built the BytCompPS and found ByCompPS.dll and registered it using regsvr32 command. Now, i have added a new interface method as suggested by you but still im not able to access the entire array. :doh:

                      S Offline
                      S Offline
                      Stephen Hewitt
                      wrote on last edited by
                      #10

                      Paste the code highlights as I did. Also, building the proxy-stub should have included a post-build step that registered it, so you shouldn't need to do it manually.

                      Steve

                      K 1 Reply Last reply
                      0
                      • S Stephen Hewitt

                        Paste the code highlights as I did. Also, building the proxy-stub should have included a post-build step that registered it, so you shouldn't need to do it manually.

                        Steve

                        K Offline
                        K Offline
                        K ARUN KUMAR
                        wrote on last edited by
                        #11

                        Hi Stephen, What do you mean by Code highlights?

                        S 1 Reply Last reply
                        0
                        • K K ARUN KUMAR

                          Hi Stephen, What do you mean by Code highlights?

                          S Offline
                          S Offline
                          Stephen Hewitt
                          wrote on last edited by
                          #12

                          Like this[^].

                          Steve

                          K 1 Reply Last reply
                          0
                          • S Stephen Hewitt

                            Like this[^].

                            Steve

                            K Offline
                            K Offline
                            K ARUN KUMAR
                            wrote on last edited by
                            #13

                            Ya i did the same way by copying you code.Still not able to access the entire array. Can you send me a working client server codes developed in VC98 or VS2003? My Id: k_arunkumar_1217@yahoo.com

                            S 1 Reply Last reply
                            0
                            • K K ARUN KUMAR

                              Ya i did the same way by copying you code.Still not able to access the entire array. Can you send me a working client server codes developed in VC98 or VS2003? My Id: k_arunkumar_1217@yahoo.com

                              S Offline
                              S Offline
                              Stephen Hewitt
                              wrote on last edited by
                              #14

                              No, I mean paste in the important sections of your code here (like I did on the post I linked to).

                              Steve

                              K 1 Reply Last reply
                              0
                              • S Stephen Hewitt

                                No, I mean paste in the important sections of your code here (like I did on the post I linked to).

                                Steve

                                K Offline
                                K Offline
                                K ARUN KUMAR
                                wrote on last edited by
                                #15

                                IDL File Entry: [id(5),helpstring("method SetData")] HRESULT SetData([in] ULONG size, [in,size_is(size)] BYTE *pData); Method Override: STDMETHODIMP CDataProvider::SetData(ULONG size, BYTE* bytArray) { // TODO: Add your implementation code here BYTE byt[6]; int i=0; for(;*bytArray!=0;i++) { byt[i]=*bytArray; ::MessageBox(NULL,(LPCTSTR)"he","Msg",MB_OK); bytArray++; } byt[i]=0; return S_OK; } Client: IDataProvider* pServer=NULL; HRESULT hr=::CoCreateInstance(CLSID_CDataProvider,NULL,CLSCTX_LOCAL_SERVER,IID_IDataProvider,(LPVOID*)&pServer); short sSize = 5; BYTE* pBytes; //Allocate the shared Memory pBytes = reinterpret_cast(CoTaskMemAlloc(sSize * sizeof(BYTE))); if(pBytes == NULL) return; ::memset(pBytes, 0, sSize); pBytes[0]='K'; pBytes[1]='K'; pBytes[2]='R'; pBytes[3]='D'; pBytes[4]=NULL; pServer->SetData(5,pBytes); CoTaskMemFree(pBytes); //Free the shared Memory

                                S 1 Reply Last reply
                                0
                                • K K ARUN KUMAR

                                  IDL File Entry: [id(5),helpstring("method SetData")] HRESULT SetData([in] ULONG size, [in,size_is(size)] BYTE *pData); Method Override: STDMETHODIMP CDataProvider::SetData(ULONG size, BYTE* bytArray) { // TODO: Add your implementation code here BYTE byt[6]; int i=0; for(;*bytArray!=0;i++) { byt[i]=*bytArray; ::MessageBox(NULL,(LPCTSTR)"he","Msg",MB_OK); bytArray++; } byt[i]=0; return S_OK; } Client: IDataProvider* pServer=NULL; HRESULT hr=::CoCreateInstance(CLSID_CDataProvider,NULL,CLSCTX_LOCAL_SERVER,IID_IDataProvider,(LPVOID*)&pServer); short sSize = 5; BYTE* pBytes; //Allocate the shared Memory pBytes = reinterpret_cast(CoTaskMemAlloc(sSize * sizeof(BYTE))); if(pBytes == NULL) return; ::memset(pBytes, 0, sSize); pBytes[0]='K'; pBytes[1]='K'; pBytes[2]='R'; pBytes[3]='D'; pBytes[4]=NULL; pServer->SetData(5,pBytes); CoTaskMemFree(pBytes); //Free the shared Memory

                                  S Offline
                                  S Offline
                                  Stephen Hewitt
                                  wrote on last edited by
                                  #16

                                  There's many problems here. Firstly you haven't escaped the post properly so it's hard to read. For example:

                                  K ARUN KUMAR wrote:

                                  reinterpret_cast(CoTaskMemAlloc(sSize * sizeof(BYTE)));

                                  You didn't escape the < and > so some important code is missing. You didn't bother to point out explicitly which code is in the client and which is in the server. Surrounding code in <pre> and </pre> tags is generally considered polite, not to mention the fact that it makes the code more readable (uses a fixed width font). You also didn't bother to ensure the code was properly indented. In short, if you want help, put some effort in asking for it (at least as much as I do in replying!). Now onto the code....

                                  K ARUN KUMAR wrote:

                                  BYTE byt[6]; int i=0; for(;*bytArray!=0;i++) { byt[i]=*bytArray; ::MessageBox(NULL,(LPCTSTR)"he","Msg",MB_OK); bytArray++; } byt[i]=0;

                                  This doesn't make use of size. Ever heard of buffer overruns? What's with the (LPCTSTR)"he"? Get rid of the cast. If the string is of the wrong type casting just turns what would have been a compiler error into a runtime error and solves nothing.

                                  K ARUN KUMAR wrote:

                                  //Allocate the shared Memory pBytes = reinterpret_cast(CoTaskMemAlloc(sSize * sizeof(BYTE))); if(pBytes == NULL) return;

                                  CoTaskMemAlloc does ***NOT*** allocate shared memory! You don't need to use it in this case (although there is no harm in using it). Can you tell me more about what actually happens when you run it. Does the CDataProvider::SetData function get called? Does it display a MessageBox? How many times?

                                  Steve

                                  K 1 Reply Last reply
                                  0
                                  • S Stephen Hewitt

                                    There's many problems here. Firstly you haven't escaped the post properly so it's hard to read. For example:

                                    K ARUN KUMAR wrote:

                                    reinterpret_cast(CoTaskMemAlloc(sSize * sizeof(BYTE)));

                                    You didn't escape the < and > so some important code is missing. You didn't bother to point out explicitly which code is in the client and which is in the server. Surrounding code in <pre> and </pre> tags is generally considered polite, not to mention the fact that it makes the code more readable (uses a fixed width font). You also didn't bother to ensure the code was properly indented. In short, if you want help, put some effort in asking for it (at least as much as I do in replying!). Now onto the code....

                                    K ARUN KUMAR wrote:

                                    BYTE byt[6]; int i=0; for(;*bytArray!=0;i++) { byt[i]=*bytArray; ::MessageBox(NULL,(LPCTSTR)"he","Msg",MB_OK); bytArray++; } byt[i]=0;

                                    This doesn't make use of size. Ever heard of buffer overruns? What's with the (LPCTSTR)"he"? Get rid of the cast. If the string is of the wrong type casting just turns what would have been a compiler error into a runtime error and solves nothing.

                                    K ARUN KUMAR wrote:

                                    //Allocate the shared Memory pBytes = reinterpret_cast(CoTaskMemAlloc(sSize * sizeof(BYTE))); if(pBytes == NULL) return;

                                    CoTaskMemAlloc does ***NOT*** allocate shared memory! You don't need to use it in this case (although there is no harm in using it). Can you tell me more about what actually happens when you run it. Does the CDataProvider::SetData function get called? Does it display a MessageBox? How many times?

                                    Steve

                                    K Offline
                                    K Offline
                                    K ARUN KUMAR
                                    wrote on last edited by
                                    #17

                                    Sorry Steve. Im new to the message posts. I will follow ur guidelines for sure from next time. Coming to our discussion, iam getting the message box only once, meaning that only one byte is marshalled.

                                    S 1 Reply Last reply
                                    0
                                    • K K ARUN KUMAR

                                      Sorry Steve. Im new to the message posts. I will follow ur guidelines for sure from next time. Coming to our discussion, iam getting the message box only once, meaning that only one byte is marshalled.

                                      S Offline
                                      S Offline
                                      Stephen Hewitt
                                      wrote on last edited by
                                      #18

                                      Post the entire IDL file.

                                      Steve

                                      K 1 Reply Last reply
                                      0
                                      • S Stephen Hewitt

                                        Post the entire IDL file.

                                        Steve

                                        K Offline
                                        K Offline
                                        K ARUN KUMAR
                                        wrote on last edited by
                                        #19

                                        ENTIRE IDL File:

                                        import "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\prsht.idl";
                                        import "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\mshtml.idl";
                                        import "c:\program files\microsoft visual studio .net 2003\vc7\platformsdk\include\dimm.idl";
                                        import "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\mshtmhst.idl";
                                        import "c:\program files\microsoft visual studio .net 2003\vc7\platformsdk\include\docobj.idl";
                                        import "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\exdisp.idl";
                                        import "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\objsafe.idl";

                                        [
                                        object,
                                        uuid(A12EAEC2-2B64-470B-93AF-EFE0855DD3AC),
                                        dual,
                                        helpstring("IDataProvider Interface"),
                                        pointer_default(unique)
                                        ]
                                        #line 14 "d:\\vc++\\sample applications\\bytcomp\\dataprovider.h"
                                        interface IDataProvider : IDispatch {
                                        #line 16 "d:\\vc++\\sample applications\\bytcomp\\dataprovider.h"
                                        [id(1),helpstring("method GetSafeArray")] HRESULT GetSafeArray([out,retval] VARIANT *vtSafeArray);
                                        [id(2),helpstring("method SetByteData")] HRESULT SetByteData([in] BYTE *bytArray);
                                        [id(3),helpstring("method SetArray")] HRESULT SetArray([in]BSTR bstrArray);
                                        [id(4),helpstring("method SetThings")] HRESULT SetThings([in]BYTE **ppThings );
                                        [id(5),helpstring("method SetData")] HRESULT SetData([in] ULONG size, [in,size_is(size)] BYTE *pData);
                                        };

                                        [ version(1.0), uuid(0381FBF3-32C1-4AF1-B6DD-EFB51815DD72), helpstring("BytComp 1.0 Type Library") ]
                                        library BytComp
                                        {
                                        importlib("stdole2.tlb");
                                        importlib("olepro32.dll");

                                        \[
                                        	version(1.0),
                                        	uuid(8816EAAA-91D5-4DCF-BA1A-DD699529D099),
                                        	helpstring("DataProvider Class")
                                        \] 
                                        

                                        #line 36 "d:\\vc++\\sample applications\\bytcomp\\dataprovider.h"
                                        coclass CDataProvider {
                                        interface IDataProvider;
                                        };

                                        }

                                        S 1 Reply Last reply
                                        0
                                        • K K ARUN KUMAR

                                          ENTIRE IDL File:

                                          import "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\prsht.idl";
                                          import "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\mshtml.idl";
                                          import "c:\program files\microsoft visual studio .net 2003\vc7\platformsdk\include\dimm.idl";
                                          import "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\mshtmhst.idl";
                                          import "c:\program files\microsoft visual studio .net 2003\vc7\platformsdk\include\docobj.idl";
                                          import "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\exdisp.idl";
                                          import "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\objsafe.idl";

                                          [
                                          object,
                                          uuid(A12EAEC2-2B64-470B-93AF-EFE0855DD3AC),
                                          dual,
                                          helpstring("IDataProvider Interface"),
                                          pointer_default(unique)
                                          ]
                                          #line 14 "d:\\vc++\\sample applications\\bytcomp\\dataprovider.h"
                                          interface IDataProvider : IDispatch {
                                          #line 16 "d:\\vc++\\sample applications\\bytcomp\\dataprovider.h"
                                          [id(1),helpstring("method GetSafeArray")] HRESULT GetSafeArray([out,retval] VARIANT *vtSafeArray);
                                          [id(2),helpstring("method SetByteData")] HRESULT SetByteData([in] BYTE *bytArray);
                                          [id(3),helpstring("method SetArray")] HRESULT SetArray([in]BSTR bstrArray);
                                          [id(4),helpstring("method SetThings")] HRESULT SetThings([in]BYTE **ppThings );
                                          [id(5),helpstring("method SetData")] HRESULT SetData([in] ULONG size, [in,size_is(size)] BYTE *pData);
                                          };

                                          [ version(1.0), uuid(0381FBF3-32C1-4AF1-B6DD-EFB51815DD72), helpstring("BytComp 1.0 Type Library") ]
                                          library BytComp
                                          {
                                          importlib("stdole2.tlb");
                                          importlib("olepro32.dll");

                                          \[
                                          	version(1.0),
                                          	uuid(8816EAAA-91D5-4DCF-BA1A-DD699529D099),
                                          	helpstring("DataProvider Class")
                                          \] 
                                          

                                          #line 36 "d:\\vc++\\sample applications\\bytcomp\\dataprovider.h"
                                          coclass CDataProvider {
                                          interface IDataProvider;
                                          };

                                          }

                                          S Offline
                                          S Offline
                                          Stephen Hewitt
                                          wrote on last edited by
                                          #20

                                          Ok. Open the registry editor and search for the following key: {A12EAEC2-2B64-470B-93AF-EFE0855DD3AC} If you find if right click on it and select "Export". Post the contents of the file this generates.

                                          Steve

                                          K 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups