go 调用dll
最后更新于:2022-04-02 02:52:16
[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
#include
#include
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)
```
';