@^@ how to handle a pointer returned by a COM interface
-
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
-
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
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/[^]
-
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/[^]
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/[^]
-
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/[^]
hi,Jared my COM was built in pure unmanaged code.I can't use AllocCoTaskMem,can I? Vincent
-
hi,Jared my COM was built in pure unmanaged code.I can't use AllocCoTaskMem,can I? Vincent
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/[^]
-
hi,Jared my COM was built in pure unmanaged code.I can't use AllocCoTaskMem,can I? Vincent
System.AccessViolationException caught when I use CoTaskMemAlloc():(( Vincent
-
System.AccessViolationException caught when I use CoTaskMemAlloc():(( Vincent
Can you post your C# code and the IDL? Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]
-
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/[^]
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
-
Can you post your C# code and the IDL? Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]
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
-
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
Two problems are jumping out at me.
- 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.
- 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/[^]
-
Two problems are jumping out at me.
- 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.
- 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/[^]
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
-
Two problems are jumping out at me.
- 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.
- 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/[^]
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