This is a creation in Article, where the information may have evolved or changed.
Go using C's library is very simple, through the CGO this tool basically can be said to be seamless integration. Here's a demonstration of the process of encapsulating the API under Windows with CGO. Note, please update go to the latest weekly version.
First, in $GOPATH\SRC (if you don't know what $gopath is, please step here to see details) Create a new folder "W32api" below and create a new file "Kernel32.go" in it, as follows.
Package W32api
#define Win32_lean_and_mean
#include <windows.h>
Import "C"
Import "Syscall"
Func getcurrentdirectory () string {
If Buflen: = C.getcurrentdirectoryw (0, nil); Buflen! = 0 {
BUF: = Make ([]uint16, Buflen)
If Buflen: = C.getcurrentdirectoryw (Buflen, (*c.wchar) (&buf[0])); Buflen! = 0 {
Return Syscall. Utf16tostring (BUF)
}
}
Return ""
}
Save, open command line, run
Go Build W32api
Go Install W32api
At this time, W32API This package is compiled, use to see it.
Write a TestApp, the code is as follows.
Package Main
Import "W32api"
Func Main () {
println (W32api. GetCurrentDirectory ())
}
The current directory in which the file should be visible should be printed at the console after it is run. How do you feel? Is it simply outrageous? That's why go has a lot of third-party library secrets in a very short time, hehe.
Now focus on a few key points, first from the content of Kernel32.go.
#define Win32_lean_and_mean
#include <windows.h>
Import "C"
These three lines should be familiar, defining the relevant macros and header files that need to be referenced. It is important to note that there is no blank line between the import "C" and the previous line of comments! Otherwise, the compilation will fail.
After that, you can use "C." To refer to functions in the C library, this prefix can also refer to simple types such as C.char, C.schar (signed char), C.uchar (unsigned char), C.short, C.ushort (unsigned short), CI NT, c.uint (unsigned int), C.long, C.ulong (unsigned long), C.longlong (Long Long), c.ulonglong (unsigned long long), C.FL Oat, c.double.
In the case of structs, unions and enums, the following prefixes, struct_, Union_, and enum_, such as c.struct_msg, need to be added.
The handling of strings is special, and the string handler provided by CGO can only handle char types, which is not enough for programmers on windows, because most of the cases are called Unicode-style APIs. I mentioned the bug a long time ago, and this bug was once labeled Go1, but recently it was removed from the Go1 category for the reason that wchar_t is rarely seen.
There is no way, only the first to live to solve it! Actually also simple, wchar_t actually corresponds to go of the uint16 type, so if you want to use buffer, you can use slice instead, just like the above code to write the method.
Buf: = Make ([]uint16, Buflen)
if Buflen: = C.getcurrentdirectoryw (Buflen, (*c.wchar) (&buf[0])); Buflen! = 0 { return Syscall. Utf16tostring (BUF)
}
If a function simply returns a wchar_t pointer, you can get the go string using the following code.
Func utf16ptrtostring (CStr *uint16) string {
If CStr! = Nil {
US: = Make ([]uint16, 0, 256)
For P: = uintptr (unsafe. Pointer (CStr)); p + = 2 {
U: = * (*uint16) (unsafe. Pointer (P))
if u = = 0 {
return string (UTF16. Decode (US))
}
US = append (US, u)
}
}
Return ""
}
In addition, CGO is currently supported only with DLL usage under Windows and cannot be statically compiled *.lib.
Above is the initial introduction of CGO use, you can start to play yourself. Perhaps you are more interested in how to call C + + Write library, well, good question, I will introduce a more simple package method--swig, this tool you may already know, it can automatically generate the package layer! Please look forward to it!