如何用go调用windows下的c++ 开发的dll及回调进来?

lihaoyxj · · 4960 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

我的c++头文件: #ifdef __cplusplus extern "C" { #endif typedef void (__stdcall *CallBackEvent)(const char* call_event,const char* ext_id,const char* visitor_id, \ const char* from,const char* to ,const char* caller_id, int duration); //port int __stdcall Connect(const char* ip, short port); // void __stdcall DisConnect(); // int __stdcall SetEventCallBack(CallBackEvent eventcb); ......... 使用go调用的代码 import ( "fmt" "github.com/ant0ine/go-json-rest/rest" "github.com/astaxie/beego/config" "log" "strconv" "syscall" "unsafe" ) var ( _Connect_lpcc uintptr ) func abort(funcname string, err error) { panic(funcname + " failed: " + err.Error()) } func connect_server(ipstring string, port int) bool { lpcclib, err := syscall.LoadLibrary("libLPCC.dll") if err != nil { fmt.Println("load libLPCC.dll failed") } defer syscall.FreeLibrary(lpcclib) _Connect_lpcc, _ = syscall.GetProcAddress(lpcclib, "Connect") fmt.Print("ip: ", ipstring, " port: ", port) fmt.Println(" ") ret, _, callErr := syscall.Syscall(_Connect_lpcc, 2, uintptr(unsafe.Pointer(&ipstring)), uintptr(unsafe.Pointer(&port)), 0) if callErr != 0 { fmt.Println("callErr", callErr) } //return int(ret) log.Println("ret:", ret) return true } func main() { iniconf, errc := config.NewConfig("ini", "restconf.conf") //var result int64 if errc != nil { //log.Fatal(errc) fmt.Println("config file fatal") } ipstring := iniconf.String("ip") fmt.Println(ipstring) port := iniconf.String("port") fmt.Println(port) nPort, err := strconv.Atoi(port) if err != nil { nPort = 9020 } bres := connect_server(ipstring, nPort) if bres == true { fmt.Println("connected") } else { fmt.Println("connect failed") } } 在go build后运行的结果 C:\works\Go>LPCCRest.exe 127.0.0.1 9020 ip: 127.0.0.1port: 9020 Exception 0xc0000005 0x0 0xc 0x310e414d PC=0x310e414d signal arrived during cgo execution main.connect_server(0x10eb25d0, 0x9, 0x233c, 0x0) C:/works/Go/LPCCRest.go:40 +0x387 main.main() C:/works/Go/LPCCRest.go:67 +0x2c2 eax 0x0 ebx 0x10ef3e94 ecx 0x7239 edx 0x0 edi 0x31076e30 esi 0x0 ebp 0x6fec0 esp 0x6fc18 eip 0x310e414d eflags 0x10246 cs 0x1b fs 0x3b gs 0x0 C:\works\Go> 而网友的调用win32 api的则可以正常地连接 package main /* * title:golang调用kernel32.dll 设置console标题,获取系统磁盘列表以及容量 * author:tjzaimee@163.com * date:2013-12-27 */ import ( "fmt" "syscall" "unsafe" "runtime" "os" "strconv" ) var( _SetConsoleTitle uintptr _GetLogicalDriveStrings uintptr _GetDiskFreeSpaceEx uintptr ) func init(){ kernel32, loadErr := syscall.LoadLibrary("kernel32.dll") if loadErr != nil{ fmt.Println("loadErr",loadErr) } defer syscall.FreeLibrary(kernel32) _SetConsoleTitle,_ = syscall.GetProcAddress(kernel32,"SetConsoleTitleW") _GetLogicalDriveStrings,_ = syscall.GetProcAddress(kernel32,"GetLogicalDriveStringsW") _GetDiskFreeSpaceEx, _ = syscall.GetProcAddress(kernel32,"GetDiskFreeSpaceExW") } func FormatSpace(str string,pos int) string{ if pos > len(str){ var space string for i:= 0; i < pos-len(str); i++{ space += " " } str = space+str } return str } func SetConsoleTitle(title string) int { ret, _, callErr := syscall.Syscall(_SetConsoleTitle,1,uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),0,0) if callErr != 0 { fmt.Println("callErr", callErr) } return int(ret) } func GetLogicalDriveStrings() []string{ lpBuffer := make([]byte,256) _,_,callErr := syscall.Syscall(_GetLogicalDriveStrings,2,uintptr(len(lpBuffer)),uintptr(unsafe.Pointer(&lpBuffer[0])),0) if callErr != 0 { fmt.Println("callErr", callErr) } disk := []string{} for _,v := range lpBuffer{ if v >= 65 && v <= 90{ disk = append(disk,string(v)+":") } } return disk } func GetDiskFreeSpaceEx(disk []string){ fmt.Println("-------------------------------------") fmt.Println("驱动器 可用(MB) 总共(MB) 已用(MB)") fmt.Println("-------------------------------------") for _,v := range disk{ lpFreeBytesAvailable := int64(0) lpTotalNumberOfBytes := int64(0) lpTotalNumberOfFreeBytes := int64(0) ret, _, _ := syscall.Syscall6(uintptr(_GetDiskFreeSpaceEx), 4, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v))), uintptr(unsafe.Pointer(&lpFreeBytesAvailable)), uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)), uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)), 0, 0) if ret != 0{ totalNumberOfFree := strconv.Itoa(int(lpTotalNumberOfFreeBytes/1024/1024)) totalNumberOfFree = FormatSpace(totalNumberOfFree,6) totalNumber := strconv.Itoa(int(lpTotalNumberOfBytes/1024/1024)) totalNumber = FormatSpace(totalNumber,6) noFreeNumber := strconv.Itoa(int((lpTotalNumberOfBytes-lpTotalNumberOfFreeBytes)/1024/1024)) noFreeNumber = FormatSpace(noFreeNumber,6) fmt.Printf("%s %s %s %s\n", v,totalNumberOfFree,totalNumber,noFreeNumber) } } fmt.Println("-------------------------------------") } func main() { hostname,_ := os.Hostname() SetConsoleTitle(hostname+"计算机详细参数") fmt.Printf("%s/%s\n",hostname,os.Getenv("username")) fmt.Printf("%s %s CPU: %d\n",os.Getenv("OS"),os.Getenv("PROCESSOR_ARCHITECTURE"),runtime.NumCPU()) disk := GetLogicalDriveStrings() GetDiskFreeSpaceEx(disk) fmt.Scanln() }

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4960 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传