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. Marshalling problem

Marshalling problem

Scheduled Pinned Locked Moved COM
comsysadmindata-structureshelpquestion
16 Posts 4 Posters 0 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.
  • D Offline
    D Offline
    David_Leikis
    wrote on last edited by
    #1

    I am trying to get an array created in a COM Server and passed back to the client by the mechanism: [out, size_is(,*pNum_ROI_nodes)] float **pROI_coords from the .idl file. Where the pNum_ROI_nodes is the size of the array and pROI_coords is the name of the array. Problem: I am receiving only one value back in this array on the client side. I have verified that only one value is being allocated in the array by the marshaller in the client side. All data is being loaded into the server side of this array (where it is being created by (float*) CoTaskMemAlloc((resultNodes * 2) * sizeof(float))) The data on the client side is the very first value loaded into it by the server and nothing else except 0x0d f0 ad ba in the second location. (bad food) Is there some setting for the COM that is confusing the marshaller? The above [out, size_is(,*pNum_ROI_nodes)] float **pROI_coords is only in the *.idl file. Should it be somewhere else as well?? The marshaller just doesn't seem to be getting the idea that there is an array, rather a single value. Thanks in advance, David

    V L 2 Replies Last reply
    0
    • D David_Leikis

      I am trying to get an array created in a COM Server and passed back to the client by the mechanism: [out, size_is(,*pNum_ROI_nodes)] float **pROI_coords from the .idl file. Where the pNum_ROI_nodes is the size of the array and pROI_coords is the name of the array. Problem: I am receiving only one value back in this array on the client side. I have verified that only one value is being allocated in the array by the marshaller in the client side. All data is being loaded into the server side of this array (where it is being created by (float*) CoTaskMemAlloc((resultNodes * 2) * sizeof(float))) The data on the client side is the very first value loaded into it by the server and nothing else except 0x0d f0 ad ba in the second location. (bad food) Is there some setting for the COM that is confusing the marshaller? The above [out, size_is(,*pNum_ROI_nodes)] float **pROI_coords is only in the *.idl file. Should it be somewhere else as well?? The marshaller just doesn't seem to be getting the idea that there is an array, rather a single value. Thanks in advance, David

      V Offline
      V Offline
      Vi2
      wrote on last edited by
      #2

      The standard TypeLib marshaller knows nothing about [size_is] keyword for parameter and cannot be used here. Instead you should build the Proxy/Stub DLL and use it to marshal this interface. With best wishes, Vita

      D R 2 Replies Last reply
      0
      • D David_Leikis

        I am trying to get an array created in a COM Server and passed back to the client by the mechanism: [out, size_is(,*pNum_ROI_nodes)] float **pROI_coords from the .idl file. Where the pNum_ROI_nodes is the size of the array and pROI_coords is the name of the array. Problem: I am receiving only one value back in this array on the client side. I have verified that only one value is being allocated in the array by the marshaller in the client side. All data is being loaded into the server side of this array (where it is being created by (float*) CoTaskMemAlloc((resultNodes * 2) * sizeof(float))) The data on the client side is the very first value loaded into it by the server and nothing else except 0x0d f0 ad ba in the second location. (bad food) Is there some setting for the COM that is confusing the marshaller? The above [out, size_is(,*pNum_ROI_nodes)] float **pROI_coords is only in the *.idl file. Should it be somewhere else as well?? The marshaller just doesn't seem to be getting the idea that there is an array, rather a single value. Thanks in advance, David

        L Offline
        L Offline
        Lim Bio Liong
        wrote on last edited by
        #3

        Hello David, I assume that you have declared your array-returning method similar to the following : [helpstring("method GetFloatArray01")] HRESULT GetFloatArray01([out] LONG* pNum_ROI_nodes, [out, size_is(,*pNum_ROI_nodes)] FLOAT** pROI_coords); Now, in your code for the server which implements this method, did you assign a proper value for "pNum_ROI_nodes" ? I created a sample implementation as follows : STDMETHOD(GetFloatArray01) (long * pNum_ROI_nodes, float * * pROI_coords) { long resultNodes = 5; *pNum_ROI_nodes = resultNodes * 2; // <-- important. *pROI_coords = (float*)CoTaskMemAlloc((resultNodes * 2) * sizeof(float)); (*pROI_coords)[0] = 1.0; (*pROI_coords)[1] = 2.0; (*pROI_coords)[2] = 3.0; (*pROI_coords)[3] = 4.0; (*pROI_coords)[4] = 5.0; (*pROI_coords)[5] = 6.0; (*pROI_coords)[6] = 7.0; (*pROI_coords)[7] = 8.0; (*pROI_coords)[8] = 9.0; (*pROI_coords)[9] = 10.0; return S_OK; } Best of luck, Bio.

        D 1 Reply Last reply
        0
        • V Vi2

          The standard TypeLib marshaller knows nothing about [size_is] keyword for parameter and cannot be used here. Instead you should build the Proxy/Stub DLL and use it to marshal this interface. With best wishes, Vita

          D Offline
          D Offline
          David_Leikis
          wrote on last edited by
          #4

          Thank you for your posting, but I need some more info on how to do what you suggested. Could you tell me some steps on how to do this and how is it different than what I have already done? I don't know the difference. Regards, David

          V 1 Reply Last reply
          0
          • L Lim Bio Liong

            Hello David, I assume that you have declared your array-returning method similar to the following : [helpstring("method GetFloatArray01")] HRESULT GetFloatArray01([out] LONG* pNum_ROI_nodes, [out, size_is(,*pNum_ROI_nodes)] FLOAT** pROI_coords); Now, in your code for the server which implements this method, did you assign a proper value for "pNum_ROI_nodes" ? I created a sample implementation as follows : STDMETHOD(GetFloatArray01) (long * pNum_ROI_nodes, float * * pROI_coords) { long resultNodes = 5; *pNum_ROI_nodes = resultNodes * 2; // <-- important. *pROI_coords = (float*)CoTaskMemAlloc((resultNodes * 2) * sizeof(float)); (*pROI_coords)[0] = 1.0; (*pROI_coords)[1] = 2.0; (*pROI_coords)[2] = 3.0; (*pROI_coords)[3] = 4.0; (*pROI_coords)[4] = 5.0; (*pROI_coords)[5] = 6.0; (*pROI_coords)[6] = 7.0; (*pROI_coords)[7] = 8.0; (*pROI_coords)[8] = 9.0; (*pROI_coords)[9] = 10.0; return S_OK; } Best of luck, Bio.

            D Offline
            D Offline
            David_Leikis
            wrote on last edited by
            #5

            Yes, my code is very similar to your example. 1. I have verified that the value for pNum_ROI_nodes is positive and the correct value for the situation. 2. I have seen that all of the values do get loaded into the memory assigned for the array on the server side in the server's memory space. 3. Upon return to the client side, I can see that the value returned for the pNum_ROI_nodes is still the correct value and is in the client memory space, but upon trying to read the values with: for (int i = 0; i < pNum_ROI_nodes * 2; i++) { pfCoordValue[i] = (float)pROI_coords[i]; //retrieve the values to local array } CoTaskMemFree(pROI_coords); //delete the array created within the COM server object At this point, the only value that is in the array pROI_coords, is the very first value loaded. In your example, it would be the value of 1.0. All other values are none existent and it is clear from the memory contents that the array is not initialized past one value. It appears that the marshaller is only moving one item of the array to the client side. Vita has suggested that the marshaller does not understand the size_is command, maybe he is on to something... Regards, David

            L 1 Reply Last reply
            0
            • D David_Leikis

              Yes, my code is very similar to your example. 1. I have verified that the value for pNum_ROI_nodes is positive and the correct value for the situation. 2. I have seen that all of the values do get loaded into the memory assigned for the array on the server side in the server's memory space. 3. Upon return to the client side, I can see that the value returned for the pNum_ROI_nodes is still the correct value and is in the client memory space, but upon trying to read the values with: for (int i = 0; i < pNum_ROI_nodes * 2; i++) { pfCoordValue[i] = (float)pROI_coords[i]; //retrieve the values to local array } CoTaskMemFree(pROI_coords); //delete the array created within the COM server object At this point, the only value that is in the array pROI_coords, is the very first value loaded. In your example, it would be the value of 1.0. All other values are none existent and it is clear from the memory contents that the array is not initialized past one value. It appears that the marshaller is only moving one item of the array to the client side. Vita has suggested that the marshaller does not understand the size_is command, maybe he is on to something... Regards, David

              L Offline
              L Offline
              Lim Bio Liong
              wrote on last edited by
              #6

              Hello David, Just curious about one thing, in your "for" loop : for (int i = 0; i < pNum_ROI_nodes * 2; i++) { pfCoordValue[i] = (float)pROI_coords[i]; //retrieve the values to local array } why do you loop until "pNum_ROI_nodes * 2" ? The returned "pROI_coords" should contain only "pNum_ROI_nodes" number of values right ? Regards, Bio.

              D 1 Reply Last reply
              0
              • L Lim Bio Liong

                Hello David, Just curious about one thing, in your "for" loop : for (int i = 0; i < pNum_ROI_nodes * 2; i++) { pfCoordValue[i] = (float)pROI_coords[i]; //retrieve the values to local array } why do you loop until "pNum_ROI_nodes * 2" ? The returned "pROI_coords" should contain only "pNum_ROI_nodes" number of values right ? Regards, Bio.

                D Offline
                D Offline
                David_Leikis
                wrote on last edited by
                #7

                The array contains the x and y coordinates of each of the nodes that have been found and therefore is two times the number of nodes. They are just packed in sequential pairs. BTW, this method that I am trying to get going is from a text "Com+ Programming" by Pradeep Tapadiya. It just seems as though this might work if I have the proper settings??? I have seen it on MSDN and other postings as well. Do you understand what Vita was talking about with a Proxy/Stub DLL and why wouldn't the TypeLib marshaller understand the size_is ? Thanks, David

                L 2 Replies Last reply
                0
                • D David_Leikis

                  Thank you for your posting, but I need some more info on how to do what you suggested. Could you tell me some steps on how to do this and how is it different than what I have already done? I don't know the difference. Regards, David

                  V Offline
                  V Offline
                  Vi2
                  wrote on last edited by
                  #8

                  Look at main cpp file. Here you can find the useful information. Something like that: // XXXX.cpp : Implementation of WinMain or DLL Exports. // Note: Proxy/Stub Information // To build a separate proxy/stub DLL, // run nmake -f XXXXps.mk in the project directory. With best wishes, Vita

                  D 1 Reply Last reply
                  0
                  • V Vi2

                    Look at main cpp file. Here you can find the useful information. Something like that: // XXXX.cpp : Implementation of WinMain or DLL Exports. // Note: Proxy/Stub Information // To build a separate proxy/stub DLL, // run nmake -f XXXXps.mk in the project directory. With best wishes, Vita

                    D Offline
                    D Offline
                    David_Leikis
                    wrote on last edited by
                    #9

                    I tried to do that from a command prompt window, but got an error: fatal error C1189: You need a Windows2000 or later to run this stub because it uses the following features: NMAKE: error U1077: 'cl' return code '0x2'. Stop. Any ideas? David

                    V 1 Reply Last reply
                    0
                    • D David_Leikis

                      The array contains the x and y coordinates of each of the nodes that have been found and therefore is two times the number of nodes. They are just packed in sequential pairs. BTW, this method that I am trying to get going is from a text "Com+ Programming" by Pradeep Tapadiya. It just seems as though this might work if I have the proper settings??? I have seen it on MSDN and other postings as well. Do you understand what Vita was talking about with a Proxy/Stub DLL and why wouldn't the TypeLib marshaller understand the size_is ? Thanks, David

                      L Offline
                      L Offline
                      Lim Bio Liong
                      wrote on last edited by
                      #10

                      Hello David, >> The array contains the x and y coordinates of each of the nodes that have been found and therefore is two times the number of nodes. They are just packed in sequential pairs. I see. However, would I be right in asserting the following : 1. The array is one dimensional nevertheless, as far as COM is concerned. 2. The fact that you have packed pairs of values in the array is a high-level design point. If I'm correct about the above two points, then take note that "pNum_ROI_nodes" needs to be set to the actual number of elements in the array (which, from a high-level standpoint, would be "two times the number of nodes"). It should not return the "total number of nodes divided by two" - this is a high-level design issue and will not be understood by COM. The "for" loop in your client code may need to be modified in view of the fact that the logic behind the value of "pNum_ROI_nodes" is now different. >> Do you understand what Vita was talking about with a Proxy/Stub DLL and why wouldn't the TypeLib marshaller understand the size_is ? Yes, David. Due to the fact that you are using a non-OLE-automation-compatible array (OLE-automation-compatible arrays would require the use of SAFEARRAYs, the size_is attribute is not relevant here), a Proxy/Stub DLL is required so that the marshaller knows how to properly handle your method and your array (between the server and the client). The TypeLib marshaller is used when your interface is based on IDispatch and all parameters are based on automation-compatible types. If you are using VC++ 7.0 (i.e. from Visual Studio .NET), a proxy/stub DLL project is generated automatically for you by the wizard, but you would need to make sure you fully build it. Once it is built, the wizard will register it. Once it is registered, the marshaller will know where to locate it and use it during client run time. If you are using VC++ 6.0, you would need to build the proxy/stub project and dll manually. Best Regards, Bio.

                      D 1 Reply Last reply
                      0
                      • D David_Leikis

                        The array contains the x and y coordinates of each of the nodes that have been found and therefore is two times the number of nodes. They are just packed in sequential pairs. BTW, this method that I am trying to get going is from a text "Com+ Programming" by Pradeep Tapadiya. It just seems as though this might work if I have the proper settings??? I have seen it on MSDN and other postings as well. Do you understand what Vita was talking about with a Proxy/Stub DLL and why wouldn't the TypeLib marshaller understand the size_is ? Thanks, David

                        L Offline
                        L Offline
                        Lim Bio Liong
                        wrote on last edited by
                        #11

                        Hello David, This is a long shot, David, but I believe that your proxy/stub dll is probably already built and registered. Otherwise, once you call the method (which returns the array), an error would occur. It could still be that the proxy/stub dll needs to be updated (following some changes to the IDL). Just a guess. - Bio.

                        1 Reply Last reply
                        0
                        • L Lim Bio Liong

                          Hello David, >> The array contains the x and y coordinates of each of the nodes that have been found and therefore is two times the number of nodes. They are just packed in sequential pairs. I see. However, would I be right in asserting the following : 1. The array is one dimensional nevertheless, as far as COM is concerned. 2. The fact that you have packed pairs of values in the array is a high-level design point. If I'm correct about the above two points, then take note that "pNum_ROI_nodes" needs to be set to the actual number of elements in the array (which, from a high-level standpoint, would be "two times the number of nodes"). It should not return the "total number of nodes divided by two" - this is a high-level design issue and will not be understood by COM. The "for" loop in your client code may need to be modified in view of the fact that the logic behind the value of "pNum_ROI_nodes" is now different. >> Do you understand what Vita was talking about with a Proxy/Stub DLL and why wouldn't the TypeLib marshaller understand the size_is ? Yes, David. Due to the fact that you are using a non-OLE-automation-compatible array (OLE-automation-compatible arrays would require the use of SAFEARRAYs, the size_is attribute is not relevant here), a Proxy/Stub DLL is required so that the marshaller knows how to properly handle your method and your array (between the server and the client). The TypeLib marshaller is used when your interface is based on IDispatch and all parameters are based on automation-compatible types. If you are using VC++ 7.0 (i.e. from Visual Studio .NET), a proxy/stub DLL project is generated automatically for you by the wizard, but you would need to make sure you fully build it. Once it is built, the wizard will register it. Once it is registered, the marshaller will know where to locate it and use it during client run time. If you are using VC++ 6.0, you would need to build the proxy/stub project and dll manually. Best Regards, Bio.

                          D Offline
                          D Offline
                          David_Leikis
                          wrote on last edited by
                          #12

                          Thanks for your answers Bio. I am using VC++6.0 so I have to build it manually. I have tried to run the nmake command from a command prompt at the top of the project .cpp file... // Note: Proxy/Stub Information // To build a separate proxy/stub DLL, // run nmake -f SPDComps.mk in the project directory. This is the error that I got. fatal error C1189: You need a Windows2000 or later to run this stub because it uses the following features: NMAKE: error U1077: 'cl' return code '0x2'. Stop. Lim Bio Liong wrote: If you are using VC++ 6.0, you would need to build the proxy/stub project and dll manually. I can also use SAFEARRAY's but I didn't have much better luck using them. I didn't seem to get anything back then. I may try that also. Maybe I have learned something more in the last few days of trying this...:) David

                          L 1 Reply Last reply
                          0
                          • D David_Leikis

                            Thanks for your answers Bio. I am using VC++6.0 so I have to build it manually. I have tried to run the nmake command from a command prompt at the top of the project .cpp file... // Note: Proxy/Stub Information // To build a separate proxy/stub DLL, // run nmake -f SPDComps.mk in the project directory. This is the error that I got. fatal error C1189: You need a Windows2000 or later to run this stub because it uses the following features: NMAKE: error U1077: 'cl' return code '0x2'. Stop. Lim Bio Liong wrote: If you are using VC++ 6.0, you would need to build the proxy/stub project and dll manually. I can also use SAFEARRAY's but I didn't have much better luck using them. I didn't seem to get anything back then. I may try that also. Maybe I have learned something more in the last few days of trying this...:) David

                            L Offline
                            L Offline
                            Lim Bio Liong
                            wrote on last edited by
                            #13

                            Hello David, You are most welcome, David. Did you manage to resolve the issue ? >> I am using VC++6.0 so I have to build it manually. I have tried to run the nmake command from a command prompt at the top of the project .cpp file... It might be easier to build a proxy/stub DLL project within the Visual C++ IDE itself. It isn't very difficult. I'll try to come up with a sample for you soonest possible (give me a short while to get this organized). >> I can also use SAFEARRAY's but I didn't have much better luck using them. You'd need to learn several COM APIs that pertain to SafeArrays. It may take a while but may be worth it if one day you may have VB clients or clients that run as scripts. Will get back to you soonest possible. Meantime, pls send me a test email so that I can reply a post with some sample codes when it's ready. My email is : bio_lim_2004@yahoo.com Best Regards, Bio.

                            1 Reply Last reply
                            0
                            • D David_Leikis

                              I tried to do that from a command prompt window, but got an error: fatal error C1189: You need a Windows2000 or later to run this stub because it uses the following features: NMAKE: error U1077: 'cl' return code '0x2'. Stop. Any ideas? David

                              V Offline
                              V Offline
                              Vi2
                              wrote on last edited by
                              #14

                              I don't know what should you do in this case. I didn't use the command prompt window. 1. You can create (and add to existing DSW) the new project which will produce the Proxy DLL. The type of this project is "Makefile" selected from all available projects. 2a. You can add the xxxps.mk file into "Source" files of your project and specify the "Custom Build" for this entry. 2b. You can specify the "Custom Build" (or "Post-biuld step") for your project entry to make and register the Proxy DLL. IOW, let the VC IDE to run NMAKE into correct environment formed by IDE. With best wishes, Vita

                              R 1 Reply Last reply
                              0
                              • V Vi2

                                The standard TypeLib marshaller knows nothing about [size_is] keyword for parameter and cannot be used here. Instead you should build the Proxy/Stub DLL and use it to marshal this interface. With best wishes, Vita

                                R Offline
                                R Offline
                                RikaBoy
                                wrote on last edited by
                                #15

                                [Message Deleted]

                                1 Reply Last reply
                                0
                                • V Vi2

                                  I don't know what should you do in this case. I didn't use the command prompt window. 1. You can create (and add to existing DSW) the new project which will produce the Proxy DLL. The type of this project is "Makefile" selected from all available projects. 2a. You can add the xxxps.mk file into "Source" files of your project and specify the "Custom Build" for this entry. 2b. You can specify the "Custom Build" (or "Post-biuld step") for your project entry to make and register the Proxy DLL. IOW, let the VC IDE to run NMAKE into correct environment formed by IDE. With best wishes, Vita

                                  R Offline
                                  R Offline
                                  RikaBoy
                                  wrote on last edited by
                                  #16

                                  Hi Vita, I can see you are good with COM and C#. I am new to use c# and I did not use COM before. I would appreciate if you could help me. I need to execute Cache methods from c# programm. Now Cache does not have yet any interface to c#, but there is COM for c++ 6. Using this COM in c# I can open Cache DB, but I cannot (I do not know how) to access properties of the classes stored in Cache database. I exported Cache classes in ODL format. Cache created this file that has uuid and id for every method I created in Cache. Now, my problem is how can I call these methods in C#? I would appreciate if you could refere where can I find any code how to call methods when I have them in odl file. Thanks in advance, RikaBoy -- modified at 3:46 Saturday 27th August, 2005

                                  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