把 CsharpExport.dll
复制到 CsharpAot
项目中 , 并配置 始终复制 。
文章插图
在
CsharpAot
的 Native
中加上:[LibraryImport("CsharpExport.dll", SetLastError = true)][return: MarshalAs(UnmanagedType.I4)]internal static partial Int32 Add(Int32 a, Int32 b);
文章插图
然后在代码中使用:
static void Main(){var result = Native.Add(1, 2);Console.WriteLine($"1 + 2 = {result}");Console.ReadKey();}
在 Visual Studio 里启动 Debug 调试:文章插图
可以看到,是正常运行的 。
接着,将
CsharpAot
项目发布为 AOT 后,再次执行:文章插图
可以看到,.NET AOT 调用 .NET AOT 的代码是没有问题的 。
Golang 部分Go 生成 Windows 动态链接库,需要安装 GCC,通过 GCC 编译代码生成对应平台的文件 。
安装 GCC需要安装 GCC 10.3,如果 GCC 版本太新,会导致编译 Go 代码失败 。
打开 tdm-gcc 官网,通过此工具安装 GCC,官网地址:
https://jmeubank.github.io/tdm-gcc/download/
文章插图
下载后,根据提示安装 。
文章插图
然后添加环境变量:
D:\TDM-GCC-64\bin
文章插图
运行
gcc -v
,检查是否安装成功 , 以及版本是否正确 。文章插图
Golang 导出函数本节的知识点是 cgo , 读者可以从这里了解更多:
https://www.programmerall.com/article/11511112290/
新建一个 Go 项目:
文章插图
新建一个
main.go
文件 , 文件内容如下:package mainimport ( "fmt")import "C"//export Startfunc Start(arg string) { fmt.Println(arg)}// 没用处func main() {}
在 Golang 中 , 要导出此文件中的函数,需要加上 import "C"
,并且 import "C"
需要使用独立一行放置 。//export {函数名称}
表示要导出的函数,注意,//
和 export
之间 没有空格 。将
main.go
编译为动态链接库:go build -ldflags "-s -w" -o main.dll -buildmode=c-shared main.go
文章插图
不得不说,Go 编译出的文件 , 确实比 .NETAOT 小一些 。
前面,笔者演示了 .NET AOT 调用 .NET AOT,那么,Go 调用 Go 是否可以呢?
答案是:不可以 。
因为 Go 编译出来的 动态链接库本身带有 runtime,Go 调用
main.dll
时 ,会出现异常 。具有情况可以通过 Go 官方仓库的 Issue 了解:https://github.com/golang/go/issues/22192
这个时候,.NET 加虽然说 Go 不能调用自己,这里还是继续补全代码,进一步演示一下 。1
分 。
虽然 Go 不能调用 Go 的,但是 Go 可以调用 .NET 的 。在文章后面会介绍 。
Go 通过动态链接库调用函数的示例:
func main() { maindll := syscall.NewLazyDLL("main.dll") start := maindll.NewProc("Start") var v string = "测试代码" var ptr uintptr = uintptr(unsafe.Pointer(&v)) start.Call(ptr)}
代码执行后会报错:文章插图
.NET C# 和 Golang 互调C# 调用 Golang将
main.dll
文件复制放到 CsharpAot
项目中,设置 始终复制 。文章插图
然后在
Native
中添加以下代码:[LibraryImport("main.dll", SetLastError = true)]internal static partial void Start(IntPtr arg);
文章插图
调用
main.dll
中的函数:static void Main(){string arg = "让 Go 跑起来";// 将申请非托管内存string转换为指针IntPtr concatPointer = Marshal.StringToHGlobalAnsi(arg);Native.Start(concatPointer);Console.ReadKey();}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 我的Vue之旅 10 Gin重写后端、实现页面详情页 Mysql + Golang + Gin
- 王者荣耀古今物语怎么获取
- 王者荣耀荣耀值怎么获取
- 许褚是怎样死的(许褚最怕的三个人)
- 《火影忍者》:二代火影真正的死因是什么为什么说是不会解开的迷题
- 一个人在家该怎么玩最舒服(一个人在家很舒服的文案)
- 18岁生日怎么玩有意思(18岁生日要做的事)
- AirPods3与AirPods Pro的区别_买哪个性价比更高?
- 朋友婚礼送礼物排行:最实用且最有意义的都在这里
- 鼠标划着划着不动了怎么办(鼠标划的太快就不动了)