I raised this question to provide few examples on using C++ methods in C#.
Example based on a small Scenario: I have a structure in C++ and this is the output of a method in C++. I want to use this method in C#.
For this, I have to create a equivalent structure and wrapper method in C#. The structure returned as a pointer from C++. So, we catch that pointer from C# and marshall that pointer to structure.
enum CustomerType //C++ enum Personal = 0 , Corporate = 1 struct Customer //C++ structure _TCHAR CustomerName[ 50 ]; _TCHAR Address[ 250 ]; INT32 CustomerNumber; CustomerType CustomerType; bool IsHandicapped; //C++ method __declspec ( dllexport ) HRESULT ReadCustomer(LPCTSTR cNumber, LPVOID *pCustomer) ..... ..... Customer* objCustomer = (Customer*)CoTaskMemAlloc( sizeof (Customer)); ...... //Fill customer ...... *pCustomer = (LPVOID)(objCustomer); return 0L ; catch (...) The above C++ structures and methods are in native "Customer.dll"
public enum CustomerType // C# enum Personal = 0 , Corporate = 1 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] // C# structure public struct Customer [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50 )] public String CustomerName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 250 )] public String Address; public int CustomerNumber; public CustomerType CustomerType; [MarshalAs(UnmanagedType.U1)] public bool IsHandicapped; // Equivalent C# wrapper method [DllImport( " Customer.dll" , EntryPoint = " ReadCustomer" , CallingConvention = CallingConvention.Cdecl)] private extern static int GetCustomerDetails([MarshalAs(UnmanagedType.LPTStr)] string cNumber , out IntPtr pCustomer); I will implement a method to use this wrapper to get customer details and marshal the pointer to structure.
public Customer GetCustomerDetails( string cNumber, out bool bStatus) int result = -1; bStatus = false ; IntPtr dataPtr = IntPtr .Zero; Customer objCustomer = new Customer(); result = GetCustomerDetails(cNumber, out dataPtr); if (result == 0 ) objCustomer = (Customer)Marshal.PtrToStructure(dataPtr, typeof (Customer)); Marshal.FreeHGlobal(dataPtr); bStatus = true ; bStatus = false ; catch (Exception ex) Marshal.FreeHGlobal(dataPtr); return objCustomer; Another example of C++ and equivalent C# method.
EntryManager.dll contains the below method:
__declspec ( dllimport ) LONG WINAPI CreateEntry(LPTSTR EntryLocation, LPTSTR EntryName, TCHAR** Belongings, LONG BelongingsSize) //Belongings=Array of items related to Entry
Equivalent C# method for the above is:
[DllImport( " EntryManager.dll" , EntryPoint = " CreateEntry" , CharSet = CharSet.Unicode)] static extern int CreateEntry( [MarshalAs(UnmanagedType.LPWStr)]string EntryLocation, [MarshalAs(UnmanagedType.LPWStr)]string EntryName, [MarshalAsAttribute(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] Belongings, int BelongingsSize); // In C++, we can not find the size of array dynamically as we do in C#(like objArray.Length). So, we need to send the size of array.
A different example on notification: When the data changed, notification done using callback mechanism in C++. I want to use the same mechanism in C#. When data changed, that notification should call C# callback method.
//In C++ "EntryManager.dll" typedef void ( __stdcall *CBNotifyFunc)(LPTSTR); DWORD WINAPI ChangeNotify(LPTSTR TargetLocation, int SearchScope, LPTSTR SearchFilter, CBNotify callBackFunction)
// In C# public delegate void CBNotify([MarshalAs(UnmanagedType.LPTStr)]string TargetLocation); [DllImport( " EntryManager.dll" , EntryPoint = " ChangeNotify" , CallingConvention = CallingConvention.Winapi)] public static extern UInt32 GetChangeNotifications([MarshalAs(UnmanagedType.LPWStr)]string TargetLocation, int SearchScope, [MarshalAs(UnmanagedType.LPWStr)]string SearchFilter, [In, MarshalAs(UnmanagedType.FunctionPtr)]CBNotify callBackFunction); public void FunctionCall( string name) MessageBox.Show( " dfd : " + name); // Using the above method GetChangeNotifications uint fsdf = GetChangeNotifications( " EntryLocation1" , 1 , null , FunctionCall); // This registers the Call back method. Whenever there is change, it calls FunctionCalll method.
I have provided the very basic information and code to use C++ methods and structures in C# which is enough to understand this topic.
  • Read the question carefully.
  • Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  • If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.
  • Don't tell someone to read the manual. Chances are they have and don't get it. Provide an answer or move on to the next question. Let's work to help developers, not make them feel stupid.
  •