How can I pass byte array from C++ to c# ?
-
Hi~~ I have a problem transfer byte array from directshow filter to C# application. I made simple directshow filter using C++. that filter has a interface to communication outside application. like this.. DECLARE_INTERFACE_(IGetCurrentData, IUnknown) { STDMETHOD(Get_Current_Media) (THIS_ BYTE** pData ) PURE; STDMETHOD(Get_Current_Media_Legnth) (THIS_ long& length ) PURE; }; I also declare interface in C# application to communicate with filter(C++ Dll) like this.. [ComVisible(true), ComImport, Guid("CCB4EF12-C1CC-43a4-82EF-7886C0F39EB1"), InterfaceType( ComInterfaceType.InterfaceIsIUnknown )] public interface IGetCurrentData { [PreserveSig] int Get_Current_Media([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]out byte[]ar); [PreserveSig] int Get_Current_Media_Legnth(out long length); } I use this sentence to use C# interface. byte[] pData; Get_Current_Media(out pData); but I meet an exception during runtime. I think datatype is not match. How can I solve this problem?
-
Hi~~ I have a problem transfer byte array from directshow filter to C# application. I made simple directshow filter using C++. that filter has a interface to communication outside application. like this.. DECLARE_INTERFACE_(IGetCurrentData, IUnknown) { STDMETHOD(Get_Current_Media) (THIS_ BYTE** pData ) PURE; STDMETHOD(Get_Current_Media_Legnth) (THIS_ long& length ) PURE; }; I also declare interface in C# application to communicate with filter(C++ Dll) like this.. [ComVisible(true), ComImport, Guid("CCB4EF12-C1CC-43a4-82EF-7886C0F39EB1"), InterfaceType( ComInterfaceType.InterfaceIsIUnknown )] public interface IGetCurrentData { [PreserveSig] int Get_Current_Media([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]out byte[]ar); [PreserveSig] int Get_Current_Media_Legnth(out long length); } I use this sentence to use C# interface. byte[] pData; Get_Current_Media(out pData); but I meet an exception during runtime. I think datatype is not match. How can I solve this problem?
http://www.dotnet247.com/247reference/msgs/15/77059.aspx Custom Software, Custom Solutions. Yye Software. http://www.yyesoftware.com
-
http://www.dotnet247.com/247reference/msgs/15/77059.aspx Custom Software, Custom Solutions. Yye Software. http://www.yyesoftware.com
many thanks for your response. but I have still problem. I also find this answer. but this solution is a little bit different with my problem. In this solution, C++ use C# dll. but in my case C# use C++ dll. Maybe this solution is correct. but I can't solve my problem.... please teach me... thank you. C++: long *ar = new long[8192]; for (i=0; i<8192; i++) ar[i] = i; managed->SetArrayElements(8192, ar); C#: public void SetArrayElements(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]int[] ar) { int[] bbb = new int[10240]; Array.Copy(ar, 0, bbb, 0, len); Console.WriteLine("Length= {0}, ar[0] = {1}", ar.Length, ar[0]); } --------
-
many thanks for your response. but I have still problem. I also find this answer. but this solution is a little bit different with my problem. In this solution, C++ use C# dll. but in my case C# use C++ dll. Maybe this solution is correct. but I can't solve my problem.... please teach me... thank you. C++: long *ar = new long[8192]; for (i=0; i<8192; i++) ar[i] = i; managed->SetArrayElements(8192, ar); C#: public void SetArrayElements(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]int[] ar) { int[] bbb = new int[10240]; Array.Copy(ar, 0, bbb, 0, len); Console.WriteLine("Length= {0}, ar[0] = {1}", ar.Length, ar[0]); } --------
Sorry, your topic said C++ to C#, but I think you're saying you want C# to C++. In that case, instead of using a byte *, try switching to VARIANT and SAFEARRAY. SAFEARRAY can be casted right to an CArray I believe. If you don't have control over the C++ interface, I'm not sure what to do to be quite honest with you. Custom Software, Custom Solutions. Yye Software. http://www.yyesoftware.com
-
Hi~~ I have a problem transfer byte array from directshow filter to C# application. I made simple directshow filter using C++. that filter has a interface to communication outside application. like this.. DECLARE_INTERFACE_(IGetCurrentData, IUnknown) { STDMETHOD(Get_Current_Media) (THIS_ BYTE** pData ) PURE; STDMETHOD(Get_Current_Media_Legnth) (THIS_ long& length ) PURE; }; I also declare interface in C# application to communicate with filter(C++ Dll) like this.. [ComVisible(true), ComImport, Guid("CCB4EF12-C1CC-43a4-82EF-7886C0F39EB1"), InterfaceType( ComInterfaceType.InterfaceIsIUnknown )] public interface IGetCurrentData { [PreserveSig] int Get_Current_Media([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]out byte[]ar); [PreserveSig] int Get_Current_Media_Legnth(out long length); } I use this sentence to use C# interface. byte[] pData; Get_Current_Media(out pData); but I meet an exception during runtime. I think datatype is not match. How can I solve this problem?
An unmanaged
long
is 32 bits, not 64; therefore, anint
(System.Int32
) is the correct type to marshal to your COM object. Also, yourSizeParamIndex
isn't valid. Your array is passed in parameter 0, not your size. You actually shouldn't even need to use theMarshalAsAttribute
here. Abyte[]
array is already a reference type (a managed pointer, if you will), and passing that without
yields a pointer to your pointer, just like aBYTE**
(orLPBYTE*
). Without declaringSizeParamIndex
orSizeConst
, however, you'll run into a problem. When marshalling from unmanaged to managed code (or even just passing data in unmanaged code with or without marshalling), there's no way to infer the size of an array (of whatever data type). If this is an interface you declared, you really should define another parameter that returns the number of bytes in the array - not just for the sake of .NET - but for any callers (unless the size is always known, in which case you should use theSizeConst
field in yourMarshalAsAttibute
).Software Design Engineer Developer Division Sustained Engineering, Microsoft My Articles
-
An unmanaged
long
is 32 bits, not 64; therefore, anint
(System.Int32
) is the correct type to marshal to your COM object. Also, yourSizeParamIndex
isn't valid. Your array is passed in parameter 0, not your size. You actually shouldn't even need to use theMarshalAsAttribute
here. Abyte[]
array is already a reference type (a managed pointer, if you will), and passing that without
yields a pointer to your pointer, just like aBYTE**
(orLPBYTE*
). Without declaringSizeParamIndex
orSizeConst
, however, you'll run into a problem. When marshalling from unmanaged to managed code (or even just passing data in unmanaged code with or without marshalling), there's no way to infer the size of an array (of whatever data type). If this is an interface you declared, you really should define another parameter that returns the number of bytes in the array - not just for the sake of .NET - but for any callers (unless the size is always known, in which case you should use theSizeConst
field in yourMarshalAsAttibute
).Software Design Engineer Developer Division Sustained Engineering, Microsoft My Articles
thanks for your reply. I solve that propbem. as you said to me, I use that statement...like this.. int Get_Current_Media([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]out byte[]ar, out int len); My C++(dll) module can communicate with c# application perfectly...!!! but speed is so late. approximately spend 0.5 second. So I can't use this method in my c# application. I have a plan to remake application using c++ -_- Anyway I am really thankful to your answer.