This is a creation in Article, where the information may have evolved or changed.
Recently, using Golang to call C + + DLL library file, a simple understanding of this note:
The compilation of DLLs is independent of the specific programming language and compiler.
DLLs written in various languages can call each other as long as they follow the agreed specification and invocation of DLL interfaces. For example, Windows provides a system DLL (which includes Windows APIs) that can be called in any development environment, regardless of whether it is visual Basic, Visual C + +, or Delphi
Two, DLL files need to be accessed by other programs function must be exported, there are 2 ways
The source files are as follows:
DllTestDef.h
#ifndef dlltestdef_h #define Dlltestdef_h int Add (intint y); #endif
DllTestDef.cpp
" DllTestDef.h " int Add (intint y) { return x + y;}
2.1. Add __declspec (dllexport) to the function in the. h header file, for example:
_declspec (dllexport) int Add (int a, int b);
Description: In this way, it is no problem to call the DLL if it is a C + + program (version of the same compiler). However, if it is a program in another language (such as C #, VB), an error occurs
Because the VC + + compiler for __declspec (dllexport) Declaration of the function will be a name conversion, as the above function will be converted to add@0, so you must declare in VB:
Declare Function Add Lib "DLLTestDef.dll" Alias "add@0" () as Long
The number after the @ may be different due to different parameter types. This is obviously not very convenient.
To solve this problem, we often add an extern "C" in front of the function, using the C-mode function naming convention. So for a wide range of uses our basic statement is as follows:
extern "C" _declspec (dllexport) int Add (int a, int b);
DllTestDef.h
#ifndef dlltestdef_h #define Dlltestdef_h extern"C" int Add (int int y); #endif
DllTestDef.cpp homologous files
2.2, using the. def file, in order to simplify the 2.1 long string of code, MS introduced the DEF file to facilitate our operation.
DllTestDef.h homologous files
DllTestDef.cpp homologous files
Dlltestdef.def
12
Add file to project properties inside the Linker/input inside
Third, the use of golang inside, there are 3 ways
Note that golang because of inconsistent data types and C + +, all parameters need to be converted to the UIntPtr pointer type when a parameter is required, and the process of conversion requires unsafe. Pointer pointer
Package Mainimport ("FMT" "Syscall" "unsafe") func IntPtr (nint) UIntPtr {returnuintptr (n)}func StrPtr (sstring) UIntPtr {returnUIntPtrunsafe. Pointer (Syscall. Stringtoutf16ptr (s))}func Lib_add (A, b )int) {lib:= Syscall. Newlazydll ("Lib.dll") fmt. Println ("DLL:", Lib. Name) Add:= lib. Newproc ("Add") fmt. Println ("+++++++newproc:", add,"+++++++") ret, _, Err:=Add. Call (IntPtr (a), IntPtr (b))ifErr! =Nil {fmt. Println ("The result of the Lib.dll operation is:", ret)}} Func Dlltestdef_add (A, Bint) {dlltestdef, _:= Syscall. LoadLibrary ("DllTestDef.dll") fmt. Println ("+++++++syscall. LoadLibrary:", Dlltestdef,"+++++++") defer syscall. FreeLibrary (dlltestdef) Add, err:= Syscall. GetProcAddress (Dlltestdef,"Add") fmt. Println ("GetProcAddress", add) ret, _, Err:=Syscall. Syscall (Add,2, IntPtr (a), IntPtr (b),0) ifErr! =Nil {fmt. Println ("The result of the DllTestDef.dll operation is:", ret)}} Func Dlltestdef_add2 (A, Bint) {dlltestdef:= Syscall. Mustloaddll ("DllTestDef.dll") Add:= Dlltestdef.mustfindproc ("Add") fmt. Println ("+++++++mustfindproc:", add,"+++++++") ret, _, Err:=Add. Call (IntPtr (a), IntPtr (b))ifErr! =Nil {fmt. Println ("The result of the dlltestdef operation is:", ret)}} Func Main () {Lib_add (4,5) Dlltestdef_add (4,5) DLLTESTDEF_ADD2 (4,5)}
All source Download