background
During the project, sometimes you need to invoke DLL files that are not written in C #, especially when using some third-party communication components, when developing applications through C #, you need to use the DllImport feature to make method calls. This article will guide you through the process of making this call fast.
Steps
1. Create a csharpinvokecpp solution:
2. Create a C + + Dynamic Library project:
3. In the application settings, select "DLL" and others follow the default options:
Finally click Finish to get the project:
We can see that there are some files here, where dllmain.cpp as the entry point for defining the DLL application, and its function is the same as the EXE file has a main or WinMain entry function, it is a DLL as an entry function, in fact, it is an optional file. It is called when both LoadLibrary and FreeLibrary are called at static or dynamic links. For more information, refer to (http://blog.csdn.net/benkaoya/archive/2008/06/02/2504781.aspx).
4. Now we open the CSharpInvokeCPP.CPPDemo.cpp file:
Now let's add the following:
123456789101112131415161718192021 |
// CSharpInvokeCPP.CPPDemo.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
extern
"C"
__declspec
(
dllexport
)
int
Add(
int
x,
int y)
{
return
x + y;
}
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
Divide(
int x,
int
y)
{
return
x / y;
}
|
extern "C" contains a double meaning, literally: First, the object it modifies is "extern", and secondly, the target it modifies is "C". The variables and functions modified by extern "C" are compiled and concatenated in the C language way.
The purpose of __declspec (dllexport) is to put the corresponding function into the DLL dynamic library.
The extern "C" __declspec (dllexport) is added in order to invoke DLL files of unmanaged C + + using DllImport. Because using DllImport, you can only invoke DLLs made from C-language functions.
5. Compile the project program and finally generate CSharpInvokeCPP.CPPDemo.dll and CSharpInvokeCPP.CPPDemo.lib in the debug directory
We use the Anti-compilation tool PE Explorer to view the methods inside the DLL:
It can be found that these four kinds of "subtraction" methods are included in external public functions.
6. Now to demonstrate how to use a C # project to invoke an unmanaged C + + DLL, first create a C # Console application:
7. Create a new Cppdll class on the Csharpinvokecsharp.csharpdemo project and write the following code:
1234567891011121314 |
public
class
CPPDLL
{
[DllImport(
"CSharpInvokeCPP.CPPDemo.dll"
)]
public
static
extern
int
Add(
int
x,
int
y);
[DllImport(
"CSharpInvokeCPP.CPPDemo.dll"
)]
public
static
extern
int
Sub(
int
x,
int
y);
[DllImport(
"CSharpInvokeCPP.CPPDemo.dll"
)]
public
static
extern
int
Multiply(
int
x,
int
y);
[DllImport(
"CSharpInvokeCPP.CPPDemo.dll"
)]
public
static
extern
int
Divide(
int
x,
int
y);
}
|
DllImport is used as the import entry feature for C + + DLL classes in C # and corresponds to extern "C" through static extern.
8. Also, remember to copy the DLL files generated in the Cppdemo to the bin directory of the Csharpdemo, or you can set the output directory in general, project properties, configuration properties:
Once the project is compiled, the resulting file is automatically output to Csharpdemo.
9. Then write the test code at the main entrance:
Static voidMain (string[] args) { intresult = Cppdll. ADD (Ten, -); Console.WriteLine ("Ten + = {0}", result); Result= Cppdll. Sub ( -, A); Console.WriteLine ("30-12 = {0}", result); Result= Cppdll. Multiply (5,4); Console.WriteLine ("5 * 4 = {0}", result); Result= Cppdll. Divide ( -,5); Console.WriteLine ("30/5 = {0}", result); Console.ReadLine ();}
Operation Result:
Method gets called.
10. The above method can only be called by a static method for a function in C + +. So how do you invoke a method in a class object in C + + with a static method? Now I add a header file to the Cppdemo project userinfo.h:
classUserInfo {Private: Char*M_name; intM_age; Public: UserInfo (Char* Name,intAge ) {M_name=name; M_age=Age ; } Virtual~UserInfo () {}intGetage () {returnM_age;} Char* GetName () {returnm_name;}};
In CSharpInvokeCPP.CPPDemo.cpp, add some code:
#include"malloc.h"#include"userinfo.h"typedefstruct { Charname[ +]; intAge ;} User; UserInfo*UserInfo;extern "C"__declspec (dllexport) user* Create (Char* Name,intAge ) {User* user = (user*) malloc (sizeof(User)); UserInfo=NewUserInfo (name, age); strcpy (User->name, userinfo->GetName ()); User->age = userinfo->Getage (); returnuser;}
This declares a structure, including name and age, that is used to map the structure of the C # aspect.
Note: user* in the code is a pointer, and returning is also an object pointer, in order to prevent the release of local variables after the end of the method scope.
strcpy is a function that replicates a char array.
11. Supplement the code in the Cppdll class in the Csharpdemo project:
[DllImport ("CSharpInvokeCPP.CPPDemo.dll")] Public Static externIntPtr Create (stringNameintAge ); [StructLayout (layoutkind.sequential)] Public structuser{[MarshalAs (UnmanagedType.ByValTStr, SizeConst= +)] Public stringName; Public intAge ;}
Where the struct user corresponds to the user in C + +.
12. Supplement the code in Program.cs:
IntPtr ptr = Cppdll. Create (" li Ping "); <strong><font color="#ff0000"typeof(Cppdll. User);</font></strong>Console.WriteLine ("Name: {0}, Age: {1}" , user. Name, user. Age);
Note: The Red font section, where the struct pointer is first converted to a IntPtr handle, is then converted to the structure you need by marshal.ptrtostructrue.
Operation Result:
Finally attached to my source code: Csharpinvokecpp.rar, hope to help you:)
Transferred from: http://www.cnblogs.com/liping13599168/archive/2011/03/31/2000320.html
Using C # to invoke unmanaged C + + generated DLL files on VS2010 (text)