CGO 入门系列-手把手教程2 dll动态库调用

CGO 入门系列-手把手教程2 dll动态库调用,第1张

CGO 入门系列-手把手教程2 dll动态库调用

CGO 入门系列-手把手教程2 dll动态库调用
    • 接上文:
    • go调用DLL
      • 目前go支持三种方法调用:
      • go具体实现DLL调用:
      • c++项目:暴露三个方法提供给DLL
    • 运行报错:
      • 报错问题:
      • 解决:
        • 解决方案1:goland启动设置
        • 解决方案2:环境设置(win/linux)
    • 运行结果:
    • github项目地址:
    • 未完待续...

接上文:

CGO 入门系列-手把手教程1

相信你已经初步了解了cgo的用法和用处 现在讲讲如何支持或扩展cpp和c的代码 dll动态库
go调用DLL 目前go支持三种方法调用:
syscall.NewLazyDLL
syscall.LoadLibrary
syscall.MustLoadDLL
go具体实现DLL调用:
func GoCallDll1(a, b int) uintptr {
   dllFile := syscall.NewLazyDLL(dllFileName)
   fmt.Println("dll:", dllFile.Name)
   add := dllFile.NewProc("add")
   fmt.Println("+++++++NewProc:", add, "+++++++")

   ret, _, err := add.Call(IntPtr(a), IntPtr(b))
   if err != nil && IsFinishError(err) {
      fmt.Println(dllFileName+fmt.Sprintf(":%d+%d", a, b)+"运算结果为:", ret)
   } else {
      fmt.Println(fmt.Sprintf("%+v", err))
   }
   return ret
}

func GoCallDll2(a, b int) uintptr {
   dllFile, _ := syscall.LoadLibrary(dllFileName)
   fmt.Println("+++++++syscall.LoadLibrary:", dllFile, "+++++++")
   defer syscall.FreeLibrary(dllFile)
   add, err := syscall.GetProcAddress(dllFile, "add")
   fmt.Println("GetProcAddress", add)

   ret, _, err := syscall.Syscall(add,
      2,
      IntPtr(a),
      IntPtr(b),
      0)
   if err != nil && IsFinishError(err) {
      fmt.Println(dllFileName+fmt.Sprintf(":%d+%d", a, b)+"运算结果为:", ret)
   } else {
      fmt.Println(fmt.Sprintf("%+v", err))
   }
   return ret
}

func GoCallDll3(a, b int) uintptr {
   DllTestDef := syscall.MustLoadDLL(dllFileName)
   add := DllTestDef.MustFindProc("add")

   fmt.Println("+++++++MustFindProc:", add, "+++++++")
   ret, _, err := add.Call(IntPtr(a), IntPtr(b))
   if err != nil && IsFinishError(err) {
      fmt.Println(dllFileName+fmt.Sprintf(":%d+%d", a, b)+"结果为:", ret)
   } else {
      fmt.Println(fmt.Sprintf("%+v", err))
   }
   return ret
}
c++项目:暴露三个方法提供给DLL
#include "stdafx.h"
#include 

extern "C" __declspec(dllexport) int add(int a, int b)
{
   return (a + b);
}

extern "C" __declspec(dllexport) int sub(int a, int b)
{
   return (a - b);
}

extern "C" __declspec(dllexport) void * point(void *ctx){
   printf("ctx:%pn", ctx);
   return ctx;
}
运行报错: 报错问题:
# cgo
cc1.exe: sorry, unimplemented: 64-bit mode not compiled in
解决: 解决方案1:goland启动设置
CGO_ENABLED=1;GOOS=windows;GOARCH=386

解决方案2:环境设置(win/linux)
Windows:
SET CGO_ENABLED=1
SET GOOS=windows
SET GOARCH=386
go build -o server.exe main.go

Linux:
SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build -o server main.go
运行结果:

github项目地址:

https://github.com/zld126126/MyGolang/tree/main/go_dll

未完待续…

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/zaji/4751859.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-08
下一篇2022-11-08

发表评论

登录后才能评论

评论列表(0条)

    保存