1. Calling public methods directly in C + + class Library
Use the DllImport attribute to invoke a method, such as a public method in a C + + class library SampleCppWrapper.dll:
extern " C " int __stdcall Add (intint n2);
__stdcall represents the calling convention: parameters are passed from right to left through the stack, and function calls are cleaned up by the callee before they are returned.
In C #, the call is as follows:
[DllImport ("SampleCppWrapper.dll")] Private Static extern int ADD (intint n2);
Note the type of the parameter, which can then be used directly in C # programming.
2. Methods for invoking classes in C + + class libraries
C # cannot directly invoke classes in a C + + class library, and requires a workaround that exposes the class member methods to be invoked by making a C + + class library, such as the following C + + class:
SampleCppClass.h
#pragma onceclass __declspec (dllexport) samplecppclass{public: Samplecppclass (void); ~samplecppclass (void); int ADD (intint n2); int Sub (intint n2);};
SampleCppClass.cpp
#include samplecppclass.h " samplecppclass::samplecppclass ( void ~samplecppclass ( void int N1, N2) { return N1 + N2;} int Samplecppclass::sub (int N1, int N2) { return N1- N2;}
We're going to call the add and sub two methods in Samplecppclass, so we'll write a C + + class library that indirectly calls the class member method through public methods:
SampleCppWrapper.h
#pragmaOnce#include".. \samplecppclass\samplecppclass.h"namespacesamplecppwrapper{extern "C"__declspec (dllexport)int__stdcall Add (intN1,intn2); extern "C"__declspec (dllexport)int__stdcall Sub (intN1,intn2);}
SampleCppWrapper.cpp
#include samplecppwrapper.h Span style= "color: #800000;" > " namespace samplecppwrapper{ Samplecppclass * g_pobj = new Samplecppclass (); int __stdcall Add (int N1, int N2) { return g_pobj->add (N1, N2); int __stdcall Sub (int N1, int N2) { return g_pobj->sub (N1, N2); }}
In C #, call the public method in SampleCppWrapper.dll:
[DllImport ("SampleCppWrapper.dll")] Private Static extern int ADD (intint n2); [ DllImport ("SampleCppWrapper.dll")]private Staticexternint Sub (intint n2);
3. Using the callback function in C + + class Library
C + + 's callback function is an event response mechanism similar to a C # delegate, such as a callback function in a C + + class:
SampleCppClass.h
#pragmaOncetypedefvoid(*loopcallback) (void*pContext);class__declspec (dllexport) samplecppclass{ Public: Samplecppclass (void); ~samplecppclass (void); voidSetcallbackfunc (Loopcallback callback); voidSetcallbackcontext (void*pContext); voidLoop ();Private: Loopcallback m_callback; void*M_pcontext;};
SampleCppClass.cpp
#include"SampleCppClass.h"Samplecppclass::samplecppclass (void) {}samplecppclass::~samplecppclass (void){}voidSamplecppclass::setcallbackfunc (Loopcallback callback) {M_callback=callback;}voidSamplecppclass::setcallbackcontext (void*PContext) {M_pcontext=PContext;}voidSamplecppclass::loop () { for(intI=0; i<Ten; i++) { if(M_callback! =NULL) {M_callback (M_pcontext); } }}
We use C + + to write a class library to encapsulate, exposing the methods in the class:
SampleCppWrapper.h
#pragmaOnce#include".. \samplecppclass\samplecppclass.h"namespacesamplecppwrapper{typedefvoid(__stdcall *loopcallbackwrapper) (void*pContext); extern "C"__declspec (dllexport)void__stdcall Setcallbackfunc (Loopcallbackwrapper callback); extern "C"__declspec (dllexport)void__stdcall Setcallbackcontext (void*pContext); extern "C"__declspec (dllexport)void__stdcall Loop ();}
SampleCppWrapper.cpp
#include"SampleCppWrapper.h"namespacesamplecppwrapper{Loopcallbackwrapper G_callbackwrapper; Samplecppclass* G_pobj =NewSamplecppclass (); voidLoopcallbackfunc (void*pContext); void__stdcall Setcallbackfunc (Loopcallbackwrapper callback) {G_callbackwrapper=callback; G_pobj-Setcallbackfunc (Loopcallbackfunc); } void__stdcall Setcallbackcontext (void*PContext) {G_pobj-Setcallbackcontext (PContext); } void__stdcall Loop () {g_pobj-Loop (); } voidLoopcallbackfunc (void*PContext) { if(G_callbackwrapper! =NULL) {G_callbackwrapper (PContext); } }}
Then, make the call in C #:
usingSystem;usingSystem.Runtime.InteropServices;usingSystem.Windows.Forms;namespacesamplecstest{ Public Partial classForm1:form {[StructLayout (layoutkind.sequential)]Private classContext { PublicForm1 Form {Get;Set; } } Private Delegate voidLoopcallbackhandler (IntPtr pContext); Private StaticLoopcallbackhandler callback =Loopcallback; [DllImport ("SampleCppWrapper.dll")] Private Static extern voidSetcallbackfunc (Loopcallbackhandler callback); [DllImport ("SampleCppWrapper.dll")] Private Static extern voidSetcallbackcontext (IntPtr pContext); [DllImport ("SampleCppWrapper.dll")] Private Static extern voidLoop (); PrivateContext CTX =NewContext (); PublicForm1 () {InitializeComponent (); } Private voidForm1_Load (Objectsender, EventArgs e) {Setcallbackfunc (callback); CTx. Form= This; IntPtr ptr=Marshal.allochglobal (marshal.sizeof (CTX)); Marshal.structuretoptr (CTX, PTR,false); Setcallbackcontext (PTR); } Private voidButton1_Click (Objectsender, EventArgs e) {Loop (); } Private Static voidLoopcallback (IntPtr pContext) {Context CTX= (Context) marshal.ptrtostructure (PContext,typeof(Context)); CTx. Form.textBox1.Text+="Callback"+Environment.NewLine; } }}
C # Several ways to invoke C + + class libraries