I. C # static calling of C ++ Dynamic Links
1. Create a VC project cppdemo. Select Win32 Console (DLL) and DLL when creating the project.
2. Add the code to the dlldemo. cpp file.
extern "C" __declspec(dllexport) int Add(int a,int b)
{
return a+b;
}
3. compile the project.
4. Create a new C # project, select the console application, and create the test program interopdemo.
5. Add reference in program. CS: using system. runtime. interopservices;
6. Add the following code in pulic class program:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
Namespace interopdemo
{
Class Program
{
[Dllimport ("cppdemo. dll", entrypoint = "add", exactspelling = false, callingconvention = callingconvention. cdecl)]
Public static extern int add (int A, int B); // For dllimport, see msdn
static void Main(string[] args)
{
Console.WriteLine(Add(1, 2));
Console.Read();
}
}
}
Now you can test the add program. Can you call C ++ dynamic link in C #? Of course, this is a static call, place the DLL compiled by cppdemo in the bin directory of the dlldemo program.
Ii. Dynamic calling of C ++ Dynamic Links in C #
In section 1, we talked about static calling of C ++ dynamic links. Due to dll path restrictions, it is not very convenient to use. in C #, we often host the DLL by configuring dynamic calling, for example, some common Designs
Mode: Abstract Factory, provider,
Strategy Mode, etc. Can I dynamically call C ++ dynamic links like this? As long as you still remember to use loadlibrary in C ++,
Getprocess,
Freelibrary functions can dynamically call Dynamic Links (they are included in kernel32.dll). The problem is solved. Next, we will perform a step-by-step experiment.
1. encapsulate several methods in Kernel32 to call nativemethod class cost
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace InteropDemo
{
public static class NativeMethod
{
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
public static extern int LoadLibrary(
[MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
public static extern IntPtr GetProcAddress(int hModule,
[MarshalAs(UnmanagedType.LPStr)] string lpProcName);
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
public static extern bool FreeLibrary(int hModule);
}
}
2. Use the nativemethod class to dynamically read c ++ DLL, obtain the function pointer, and encapsulate the pointer into a delegate in C. The reason is very simple. Pointers are no longer available in C #, as shown below:
int hModule = NativeMethod.LoadLibrary(@"c:"CppDemo.dll");
IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add");
For details, see the code
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
Namespace interopdemo
{
Class Program
{
// [Dllimport ("cppdemo. dll", entrypoint = "add", exactspelling = false, callingconvention = callingconvention. cdecl)]
// Public static extern int add (int A, int B); // For dllimport, see msdn
Static void main (string [] ARGs)
{
// 1. dynamically load C ++ DLL
Int hmodule = nativemethod. loadlibrary (@ "C: cppdemo. dll ");
If (hmodule = 0) return;
// 2. Read the function pointer
Intptr = nativemethod. getprocaddress (hmodule, "add ");
// 3. encapsulate the function pointer into a delegate
Add addfunction = (ADD) Marshal. getdelegateforfunctionpointer (intptr, typeof (ADD ));
// 4. Test
Console. writeline (addfunction (1, 2 ));
Console. Read ();
}
/// <Summary>
/// Function pointer
/// </Summary>
/// <Param name = "A"> </param>
/// <Param name = "B"> </param>
/// <Returns> </returns>
Delegate int add (int A, int B );
}
}
Through the above two examples, we can call the code written by C ++ dynamically or statically in C #.