C # project calls the C ++ DLL Program
First, create a C ++ solution. Then, select the win32 project in the options below. Be sure not to select the console or MFC program;
Then select DLL in the program settings. You can use other default values;
Finally, the following interface is displayed;
We can see some files, including dllmain. cpp serves as the entry point for defining DLL applications. It serves the same purpose as the main or WinMain entry function in the exe file. It serves as an entry function of the DLL, in fact, it is an optional file. It is called when LoadLibrary and FreeLibrary are called during static or dynamic connections.
Note the following: Make sure to change the Debug section below; this is the main step of X64 cooperation;
Configuration Manager changes as shown in;
Then enter the following code in CppDemo. cpp:
// The following is my program; extern "C" _ declspec (dllexport) int Sub (int x, int y) {return x-y ;} extern "C" _ declspec (dllexport) int Multiply (int x, int y) {return x * y;} extern "C" _ declspec (dllexport) int Add (int x, int y) {return x + y;} extern "C" _ declspec (dllexport) int Divide (int x, int y) {return x/y ;}
Extern "C" contains a double meaning, which can be obtained literally: first, the target is "extern", and second, the target is "C. The variables and functions modified by extern "C" are compiled and connected in C language.
_ Declspec (dllexport) aims to put the corresponding function into the DLL dynamic library.
The purpose of adding extern "C" _ declspec (dllexport) is to use DllImport to call the DLL files of unmanaged C ++. Because the use of DllImport can only call DLL made of C language functions.
Create a C # console program;
Assign the dll file in CppDemo to the X64 running directory in the C # program directory.
And add a class:
public class CPPDLL { [DllImport("CppDemo.dll")] public static extern int Add(int x,int y); [DllImport("CppDemo.dll")] public static extern int Sub(int x, int y); [DllImport("CppDemo.dll")] public static extern int Multiply(int x, int y); [DllImport("CppDemo.dll")] public static extern int Divide(int x, int y); }
Then write the following data in the main program:
int result = CPPDLL.Add(10, 20); Console.WriteLine("10 + 20 = {0}", result); result = CPPDLL.Sub(30, 12); Console.WriteLine("30 - 12 = {0}", result); result = CPPDLL.Multiply(5, 4); Console.WriteLine("5 * 4 = {0}", result); result = CPPDLL.Divide(30, 5); Console.WriteLine("30 / 5 = {0}", result); Console.ReadLine();
The running result is as follows:
The following describes class calls:
First, add a UserInfo class in CppDemo:
Add the following program to UserInfo. h;
Class UserInfo {private: char * m_Name; int m_Age; public: UserInfo (char * name, int age) {m_Name = name; m_Age = age;} virtual ~ UserInfo () {}// the virtual here is intended for future implementation; int GetAge () {return m_Age;} char * GetName () {return m_Name ;}};
The content of UserInfo. cpp is as follows:
# Include "stdafx. h "# include" malloc. h "# include" UserInfo. h "typedef struct {char name [32]; int age ;}user; // define a struct named User; UserInfo * userInfo; // declare a pointer to the UserInfo object; // The following is the interface that returns a pointer to the address; // note: the User * in the Code is a pointer and the return is also an object pointer, this is done to prevent the release of local variables after the end of the method scope. Extern "C" _ declspec (dllexport) User * Create (char * name, int age) {// malloc requests the system to allocate a specified size of memory space. // The return type is void. Void * Indicates a pointer of unknown type. User * user = (User *) malloc (sizeof (User); // allocate a piece of memory to the user; format it with the User; userInfo = new UserInfo (name, age ); // copy; strcpy (user-> name, userInfo-> GetName (); user-> age = userInfo-> GetAge (); return user ;}
Then add the following in the C # program we created earlier:
Add code to the CPPDLL class in the project:
// Class call program block; [DllImport ("CppDemo. dll ")] public static extern IntPtr Create (string name, int age); // IntPtr indicates a specific platform pointer, which is specified during use; // The StructLayout feature allows us to control the arrangement of elements in the Structure statement block in the memory, // and the running library arrangement of these elements when these elements are passed to the external DLL. [StructLayout (LayoutKind. sequential)] // controls the physical layout of struct fields. The brackets indicate layout in order of appearance; public struct User {// The financialas attribute instructs you how to mail data between hosted and unmanaged code. // The following describes the data storage capacity of the two fields. The first is the character type, and the second is the 32-bit int type. // It has two parameters, therefore, the following two rows can be managed; [financialas (UnmanagedType. byValTStr, SizeConst = 32)] public string Name; public int Age ;}Add the following code to the main program:
// The following is the class call IntPtr = CPPDLL. create ("Shawn", 25); // The conversion pointer is of the User type. Because an object is returned, it must be formatted as User; CPPDLL. user user = (CPPDLL. user) Marshal. ptrToStructure (ptr, typeof (CPPDLL. user); Console. writeLine ("Name: {0}, Age: {1}", user. name, user. age );
Note that you must recompile the C # program.
The running result is as follows;