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. C#
  4. @^@ how to handle a pointer returned by a COM interface

@^@ how to handle a pointer returned by a COM interface

Scheduled Pinned Locked Moved C#
csharpcomtutorialquestion
12 Posts 2 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
    dragooooon lee
    wrote on last edited by
    #1

    assume the following method in a COM virtual void * __stdcall Print(BSTR msg){ char * buf= new char[128]; sprintf(buf,"return by print interface"); return (void *)buf; } how should I handle the returned pointer by the method above in C#, so that I can get the proper string set by the method? :laugh: Vincent

    J 1 Reply Last reply
    0
    • D dragooooon lee

      assume the following method in a COM virtual void * __stdcall Print(BSTR msg){ char * buf= new char[128]; sprintf(buf,"return by print interface"); return (void *)buf; } how should I handle the returned pointer by the method above in C#, so that I can get the proper string set by the method? :laugh: Vincent

      J Offline
      J Offline
      Jared Parsons
      wrote on last edited by
      #2

      If this is COM you can't pass back memory allocated by new. You need to allocate the char array with AllocCoTaskMem(). After that you should just be able to to a Marshal.PtrToStringAnsi() call on the value. Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

      J D 2 Replies Last reply
      0
      • J Jared Parsons

        If this is COM you can't pass back memory allocated by new. You need to allocate the char array with AllocCoTaskMem(). After that you should just be able to to a Marshal.PtrToStringAnsi() call on the value. Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

        J Offline
        J Offline
        Jared Parsons
        wrote on last edited by
        #3

        Also, is it legal for void* to be an [out] parameter to a COM interface? IIRC this is not legal since COM would be unable to marshal the underlying data. Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

        1 Reply Last reply
        0
        • J Jared Parsons

          If this is COM you can't pass back memory allocated by new. You need to allocate the char array with AllocCoTaskMem(). After that you should just be able to to a Marshal.PtrToStringAnsi() call on the value. Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

          D Offline
          D Offline
          dragooooon lee
          wrote on last edited by
          #4

          hi,Jared my COM was built in pure unmanaged code.I can't use AllocCoTaskMem,can I? Vincent

          J D 2 Replies Last reply
          0
          • D dragooooon lee

            hi,Jared my COM was built in pure unmanaged code.I can't use AllocCoTaskMem,can I? Vincent

            J Offline
            J Offline
            Jared Parsons
            wrote on last edited by
            #5

            dragooooon lee wrote:

            my COM was built in pure unmanaged code.I can't use AllocCoTaskMem,can I?

            You can use Marashal.AllocCoTaskMem(). But I don't think that applies in this case since this is purely managed. I assumed your example was in C++. I believe that since it's all managed the CLR marshaller will do the dirty work. I haven't every written a purely managed COM interface implemenation though so I would check some documenation. Can you post the IDL file for the COM interface? That would help out a bit. Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

            D 1 Reply Last reply
            0
            • D dragooooon lee

              hi,Jared my COM was built in pure unmanaged code.I can't use AllocCoTaskMem,can I? Vincent

              D Offline
              D Offline
              dragooooon lee
              wrote on last edited by
              #6

              System.AccessViolationException caught when I use CoTaskMemAlloc():(( Vincent

              J 1 Reply Last reply
              0
              • D dragooooon lee

                System.AccessViolationException caught when I use CoTaskMemAlloc():(( Vincent

                J Offline
                J Offline
                Jared Parsons
                wrote on last edited by
                #7

                Can you post your C# code and the IDL? Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

                D 1 Reply Last reply
                0
                • J Jared Parsons

                  dragooooon lee wrote:

                  my COM was built in pure unmanaged code.I can't use AllocCoTaskMem,can I?

                  You can use Marashal.AllocCoTaskMem(). But I don't think that applies in this case since this is purely managed. I assumed your example was in C++. I believe that since it's all managed the CLR marshaller will do the dirty work. I haven't every written a purely managed COM interface implemenation though so I would check some documenation. Can you post the IDL file for the COM interface? That would help out a bit. Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

                  D Offline
                  D Offline
                  dragooooon lee
                  wrote on last edited by
                  #8

                  import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(853b4626-393a-44df-b13e-64cabe535dbf), nonextensible, pointer_default(unique) ] interface IMyComponent : IUnknown { [id(1), helpstring("method Initialize")] void * __stdcall Print(BSTR msg); }; [uuid(0c6bb614-8563-49ea-b5ce-e6b7febebc27)] coclass RtpSource { interface IMyComponent ; }; Vincent

                  1 Reply Last reply
                  0
                  • J Jared Parsons

                    Can you post your C# code and the IDL? Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

                    D Offline
                    D Offline
                    dragooooon lee
                    wrote on last edited by
                    #9

                    import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(853b4626-393a-44df-b13e-64cabe535dbf), nonextensible, pointer_default(unique) ] interface IMyComponent : IUnknown { [id(1), helpstring("method Initialize")] void * __stdcall Print(BSTR msg); }; [uuid(0c6bb614-8563-49ea-b5ce-e6b7febebc27)] coclass RtpSource { interface IMyComponent ; }; ------------------------------------------------------------ C# code IntPtr p = ((IMyComponent)rtpsource).Print(s); StringBuilder sb = new StringBuilder(); sb.Append(Marshal.PtrToStringBSTR(p)); Vincent

                    J 1 Reply Last reply
                    0
                    • D dragooooon lee

                      import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(853b4626-393a-44df-b13e-64cabe535dbf), nonextensible, pointer_default(unique) ] interface IMyComponent : IUnknown { [id(1), helpstring("method Initialize")] void * __stdcall Print(BSTR msg); }; [uuid(0c6bb614-8563-49ea-b5ce-e6b7febebc27)] coclass RtpSource { interface IMyComponent ; }; ------------------------------------------------------------ C# code IntPtr p = ((IMyComponent)rtpsource).Print(s); StringBuilder sb = new StringBuilder(); sb.Append(Marshal.PtrToStringBSTR(p)); Vincent

                      J Offline
                      J Offline
                      Jared Parsons
                      wrote on last edited by
                      #10

                      Two problems are jumping out at me.

                      1. I don't think that it's legal for a COM method to return void* without a specification of a custom marshaller. Otherwise it's impossible for COM to figure out how to Marshal the data between processes and/or apartments. Then again I'm not a COM expert so one of them might want to chirp in here.
                      2. Shouldn't the COM method be returning an HRESULT? Otherwise how do you detect failure?

                      Also, can you post the implementation of the COM interface or at least the Print method? And how did you aquire the rptsource variable (please post that code as well). Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

                      D 2 Replies Last reply
                      0
                      • J Jared Parsons

                        Two problems are jumping out at me.

                        1. I don't think that it's legal for a COM method to return void* without a specification of a custom marshaller. Otherwise it's impossible for COM to figure out how to Marshal the data between processes and/or apartments. Then again I'm not a COM expert so one of them might want to chirp in here.
                        2. Shouldn't the COM method be returning an HRESULT? Otherwise how do you detect failure?

                        Also, can you post the implementation of the COM interface or at least the Print method? And how did you aquire the rptsource variable (please post that code as well). Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

                        D Offline
                        D Offline
                        dragooooon lee
                        wrote on last edited by
                        #11

                        it's ugly since it's just a test. thanks anyway.maybe I need to read some books about interoperation to figure it out.:sigh: Vincent

                        1 Reply Last reply
                        0
                        • J Jared Parsons

                          Two problems are jumping out at me.

                          1. I don't think that it's legal for a COM method to return void* without a specification of a custom marshaller. Otherwise it's impossible for COM to figure out how to Marshal the data between processes and/or apartments. Then again I'm not a COM expert so one of them might want to chirp in here.
                          2. Shouldn't the COM method be returning an HRESULT? Otherwise how do you detect failure?

                          Also, can you post the implementation of the COM interface or at least the Print method? And how did you aquire the rptsource variable (please post that code as well). Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

                          D Offline
                          D Offline
                          dragooooon lee
                          wrote on last edited by
                          #12

                          It's ugly since it's just a test. Thanks anyway.Maybe I need to read some books about interoperation to figure it out:rolleyes: Vincent

                          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