[Mono-devel-list] Calling Native C api - Marshalling issue.
I am getting problem while executing the c library function from C#. Following is the equivalent code . C Code : --- //This is the structure in C typedef struct MyDataType { u_intdata1; u_int data2; } MyData; //This is the C function which is called by passing pointer to above structure function u_int DoSomeOperation(MyData* pData) { return pData-data1 +pData-data2; } C# Code : Following code shows how I am executing that call. using System; using System.Runtime.InteropServices; namespace Test { //Define equivalent class to MyData structure [StructLayout(LayoutKind.Sequential)] public class CSMyData { public UInt32 data1; public UInt32 data2; } public class Test { //Import the dll and define C function. [DllImport (mylibrary.dll, EntryPoint=DoSomeOperation)] static extern Int32 OperateData( ref CSMyData pData); //Other way of defining //static extern Int32 OperateData( [In,Out] CSMyData pData); //main function for console application static void Main() { UInt32 result = 0; CSMyData inData = new CSMyData(); inData.data1 = 0x; inData.data2 = 0xFF; result = OperateData(ref inData); Console.WriteLine( Addition = result.ToString(); } } } Issue: When I am printing value in the C code side ,ie in DoSomeOperation function , the values are corrupted. Please let me know what part is wrong. regards, Yogi ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-devel-list] Calling Native C api - Marshalling issue.
Hi, classes are by default passed by-ref to unmanaged code, i.e. a pointer to the data is passed to the C side. If you define your managed method as 'ref', then the unmanaged code will receive a pointer-to-a-pointer to the data. Try removing the 'ref', or defining CSMyData as a struct, which by default marshalled by-value. Zoltan On 7/28/05, Yogendra Thakur [EMAIL PROTECTED] wrote: I am getting problem while executing the c library function from C#. Following is the equivalent code . C Code : --- //This is the structure in C typedef struct MyDataType { u_intdata1; u_int data2; } MyData; //This is the C function which is called by passing pointer to above structure function u_int DoSomeOperation(MyData* pData) { return pData-data1 +pData-data2; } C# Code : Following code shows how I am executing that call. using System; using System.Runtime.InteropServices; namespace Test { //Define equivalent class to MyData structure [StructLayout(LayoutKind.Sequential)] public class CSMyData { public UInt32 data1; public UInt32 data2; } public class Test { //Import the dll and define C function. [DllImport (mylibrary.dll, EntryPoint=DoSomeOperation)] static extern Int32 OperateData( ref CSMyData pData); //Other way of defining //static extern Int32 OperateData( [In,Out] CSMyData pData); //main function for console application static void Main() { UInt32 result = 0; CSMyData inData = new CSMyData(); inData.data1 = 0x; inData.data2 = 0xFF; result = OperateData(ref inData); Console.WriteLine( Addition = result.ToString(); } } } Issue: When I am printing value in the C code side ,ie in DoSomeOperation function , the values are corrupted. Please let me know what part is wrong. regards, Yogi ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
RE: [Mono-devel-list] Calling Native C api - Marshalling issue.
Thanks Massi Zoltan. It works after removing the ref. As Zoltan said, by defualt classed are passed as reference to unmanaged code. -YoGi -Original Message- From: Massimiliano Mantione To: Yogendra Thakur Cc: 'mono-devel-list@lists.ximian.com ' Sent: 7/28/05 11:17 AM Subject: Re: [Mono-devel-list] Calling Native C api - Marshalling issue. On Thu, 2005-07-28 at 10:15 -0400, Yogendra Thakur wrote: I am getting problem while executing the c library function from C#. //Define equivalent class to MyData structure [StructLayout(LayoutKind.Sequential)] public class CSMyData { either should be a struct, not a class... //Import the dll and define C function. [DllImport (mylibrary.dll, EntryPoint=DoSomeOperation)] static extern Int32 OperateData( ref CSMyData pData); //Other way of defining //static extern Int32 OperateData( [In,Out] CSMyData pData); ...or you should omit the ref (or the [In,Out]). With these modification it works. The issue is that if CSMyData is a struct, then the ref (or the [In,Out]) is needed to get the address of the struct. But if CSMyData is a class, marshalling converts it correctly. I am no marshalling expert, but I think that if you put the ref you pass the address of the object reference :-) Ciao, Massi ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list