[TOC] `test.h` ``` #ifndef TEST_H #define TEST_H #ifdef TEST_DLL_EXPORT #define TEST_API __declspec(dllexport) #else #define TEST_API __declspec(dllimport) #endif TEST_API void greet(char *name); TEST_API char *name(); #endif ``` `test.c` ``` #define TEST_DLL_EXPORT #include "test.h" #include <stdio.h> #include <stdlib.h> #include <string.h> void greet(char *name) { printf("Hello, %s!\n", name); } char *name() { char buf[] = "Gopher"; char *n = malloc(strlen(buf) + 1); strcpy(n, buf); n[strlen(buf)] = '\0'; return n; } ``` 执行gcc,生成dll `gcc -shared -o test.dll test.c` 调用 ``` dll := syscall.MustLoadDLL("test.dll") procGreet := dll.MustFindProc("greet") procGreet.Call(uintptr(unsafe.Pointer(syscall.StringBytePtr("Cynhard")))) //StringBytePtr 可用 BytePtrFromString 替换 procName := dll.MustFindProc("name") r, _, _ := procName.Call() // 获取C返回的指针。 // 注意C返回的r为char*,对应的Go类型为*byte p := (*byte)(unsafe.Pointer(r)) // 定义一个[]byte切片,用来存储C返回的字符串 data := make([]byte, 0) // 遍历C返回的char指针,直到 '\0' 为止 for *p != 0 { data = append(data, *p) // 将得到的byte追加到末尾 r += unsafe.Sizeof(byte(0)) // 移动指针,指向下一个char p = (*byte)(unsafe.Pointer(r)) // 获取指针的值,此时指针已经指向下一个char } name := string(data) // 将data转换为字符串 fmt.Printf("Hello, %s!\n", name) ```