一听这名字,就些许骚气,耗费大半天饱读度娘,试过一个个坑,终于哭尽肝来!
//export showMsg
func showMsg(msg *C.char,len int) {
fmt.Println("show msg in go:",C.GoString(msg))
}
//export showMsg
这个不是注释,写C/C++的人儿注意了,这是Go方法导出为C方法的金钥匙!
/*
.....
*/
这里的showMsg(s,len)
就是上一步export的Go方法。
func init() {
dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
dllfile := fmt.Sprintf(`%s\test.dll`, dir)
lib := syscall.NewLazyDLL(dllfile)
setcallback = lib.NewProc("setCallback")
}
func main() {
fmt.Print("start\n")
C.sayHello()
_, _, err := setcallback.Call((uintptr)(unsafe.Pointer(C.showMsg_cgo)))
if err != syscall.Errno(0) {
fmt.Println(`调用出错,错误原因:%v`, err)
}
select
{}
}
#ifdef DLL1_EXPORTS
#define DLL1_API extern "C" __declspec(dllexport)
#else
#define DLL1_API __declspec(dllimport)
#endif
typedef void ShowInfo(char *str, int len);
DLL1_API void setCallback(ShowInfo * cb);
#include "Dll1.h"
#include
#include
using namespace std::chrono;
ShowInfo * g_showInfo = nullptr;
int g_cnt = 0;
DLL1_API void setCallback(ShowInfo * cb)
{
g_showInfo = cb;
if (g_cnt == 0) {
std::thread([&]() {
while (1) {
if (g_showInfo) {
char buf[255] = { 0 };
sprintf_s(buf, "say hello in C %d", ++g_cnt);
g_showInfo(buf, strlen(buf));
}
}
}).detach();
}
}
package main
/*
void showMsg_cgo(char *s,int len);
*/
import "C"
import (
"fmt"
"os"
"path/filepath"
"syscall"
"unsafe"
)
var (
setcallback *syscall.LazyProc // 初始化,path为库配置文件config.xml路径
)
//export showMsg
func showMsg(msg *C.char,len int) {
fmt.Println("show msg in go:",C.GoString(msg))
}
func init() {
dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
dllfile := fmt.Sprintf(`%s\test.dll`, dir)
lib := syscall.NewLazyDLL(dllfile)
setcallback = lib.NewProc("setCallback")
}
func main() {
fmt.Print("start\n")
C.sayHello()
_, _, err := setcallback.Call((uintptr)(unsafe.Pointer(C.showMsg_cgo)))
if err != syscall.Errno(0) {
fmt.Println(`调用出错,错误原因:%v`, err)
}
select
{}
}
package main
/*
#include
void showMsg_cgo(char *s ,int len)
{
showMsg(s,len);
}
*/
import "C"