In the project to provide other client program DLL as interface, the project is in. Developed under the Net4.0 platform. The end of the day. NET has compatibility issues with each version, but in order to use the new features of the high-version running platform, it is also necessary to take into account the calls of other low-version platform client programs. To solve this problem, try to add a wrapper to the interface of the higher version of the. Net dll through a C + +/CLI DLL, exposing the interface to the client program.
Supported Customer language platforms:
- VB 6.0
- Vc
- . Net 1.0/.net 1.1
- . Net 2.0
- . Net 3.5
Create C #. Class Library for Net4.0
- Create a C # project: Csharp
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespacecsharp{ Public classCsharpclass { Public intDotesting (intXintYstringtesting, out stringerror) {Error= testing +"-testing is OK."; returnX +y; } }}
Create a C + +/CLI wrapper class Library
- Create Project C + +/CLI project: Csharpwrap
- Add a reference to CSharp
// CsharpWrap.h #pragma once<windows.h> <stringusingnamespace System; using namespace Csharp; using namespace std; using namespace Runtime::interopservices;
//The is the main DLL file.#include"stdafx.h"#include"CsharpWrap.h"extern "C"_declspec (dllexport)intDotesting (intXintYChar* Testing,Char*error) { Try{Csharpclass^generator =gcnew Csharpclass (); String^ Strtesting =gcnew String (testing); String^strerror; intsum = generator->dotesting (x, y,strtesting, strerror); if(Strerror! =nullptr) { Char* Cerror = (Char*) (Marshal::stringtohglobalansi (strerror)). ToPointer (); memcpy (Error,cerror,strlen (cerror)+1); } Else{Error=nullptr; } returnsum; } Catch(Exception e) {memcpy (Error,e.what (), strlen (E.what ())+1); return-1; }}
- Csharp.dll
- CsharpWrap.dll
If you want to call CsharpWrap.dll you must ensure that Csharp.dll is also visible to the calling program (i.e. should be placed in the same directory as the process EXE file)
Calling the demo code
HINSTANCE hinst= LoadLibrary (_t ("CsharpWrap.dll"));if(hInst) {Pfunc dotesting= (Pfunc) GetProcAddress (HInst,"dotesting"); if(dotesting) {Charerror[ -]={NULL}; intsum = dotesting (1,2,"Hello", error); //Show Testing Results Charstrsum[8]; _itoa_s (Sum,strsum, -); :: MessageBoxA (NULL, error, strsum, MB_OK); } Else{:: MessageBoxA (NULL,"Get function fail.","Fail", MB_OK); } //Free LibraryFreeLibrary (HInst); HInst=nullptr;}Else{:: MessageBoxA (NULL,"Load dll fail.","Fail", MB_OK);}
Export function
[DllImport ("CsharpWrap.dll")]
Static extern int dotesting (intintstring testing, StringBuilder error);
Call
New StringBuilder ($); int Sum = dotesting (12"hellow", SB); MessageBox.Show (sb.) ToString (), Sum. ToString ());
Export function
public declare function dotesting " csharpwrap.dll (byval x as integer , byval y as integer , byval testing as string , byval error as string ) as integer
Call
Dim Error as StringDimTesting as StringDimX as IntegerDimY as IntegerDimSum as IntegerTesting="Hello"Error=String(60000, vbNullChar) sum= Dotesting (x, Y, testing,Error)
Frequently asked questions and precautions
- Issues with the Platform toolset
If you are using a C + +/CLI DLL that is compiled with more than VS2010 versions, you may experience missing dependencies and other run-time errors.
If you want to support the XP system toolset as far as possible, end with _XP
Platform Toolset's dependent DLLs, placing the following or other corresponding versions of the dependent DLLs under the C:\WINDOWS\SYSTEM32 of the target machine
-
- Msvcp100.dll
- Msvcr100.dll
- Msvcp110.dll
- Msvcr110.dll
- The problem with the character set because. NET The default character set is Unicode, but the client is likely to be a different character set, which can also cause string compatibility issues between programs.
Select Unicode/multi-byte to select the appropriate character set for non-project requirements
converting different character sets within your code
From char* to wide character
wchar_t *GETWC (constChar *c) { const size_t cSize = strlen (c) +1; wchar_tNew wchar_t[csize]; MultiByteToWideChar (CP_ACP,0, (constChar *) c,int(cSize), WC, int (cSize)); return WC;}
string^ to char*
Char* cerror = (char*) (Marshal::stringtohglobalansi (strerror)). ToPointer ();
- A problem with incoming parameters when invoking a C + +/CLI DLL
C # call when the string parameter corresponding to the type should be StringBuilder, to note the capacity of StringBuilder, the default is 256 characters, if the return of more things to pay attention to initialize the corresponding size of capacity.
- Problems with multi-layer nesting of DLLs
If you fail to load the DLL with LoadLibrary, you can try to use LoadLibraryEx, while ensuring that the dependent c#dll is placed in the process exe sibling directory.
LoadLibraryEx ("dll absolute path ", NULL, Load_with_altered_search_path);
unmanaged C + + wrapper calls C # DLL