当前位置: 首页 > news >正文

使用AoT让.NetFramework4.7.2程序调用.Net8编写的库

1、创建.Net8的库,双击解决方案中的项目,修改如下,启用AoT:

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Library</OutputType><PublishAot>true</PublishAot><IsAotCompatible>true</IsAotCompatible><CopyRefAssembliesToPublishDirectory>true</CopyRefAssembliesToPublishDirectory><TargetFramework>net8.0</TargetFramework><ImplicitUsings>enable</ImplicitUsings><Nullable>enable</Nullable></PropertyGroup>
</Project>

在Class1.cs文件中加入如下代码:

using System.Runtime.InteropServices;namespace AoT001
{public class Export{[UnmanagedCallersOnly(EntryPoint = "Add")]public static int Add(int a, int b){return a + b;}[UnmanagedCallersOnly(EntryPoint = "Combine")]public static IntPtr Combine(IntPtr str, int num){var name = nameof(Export);string? inputStr = Marshal.PtrToStringAnsi(str);string? result = $"{inputStr} -- {num} -- {name}";return Marshal.StringToHGlobalAnsi(result);}[UnmanagedCallersOnly(EntryPoint = "Free")]public static void Free(IntPtr ptr) {Marshal.FreeHGlobal(ptr);}}
}

右键,AoT库项目, 发布,弹出如下图,按步骤配置:

注意:AoT仅支持win-x64

点击发布后,启动编译过程,结果如下图:

如图,简单的dll编译后size是1.3M,因为AoT将所有的依赖库都打包到了DLL内,没有C#运行环境也可以执行。使用Dependence查看如下图:

可见AoT编译的dll已经和C或C++编译的dll兼容。在Framework4.7.2项目中可按普通C编译的dll使用,如下:

namespace Winform472
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){}private void button1_Click(object sender, EventArgs e){var sum = AoTHelp.Add(1111, 1112);var str1 = "Hello World 0001";var ptr1 = Marshal.StringToHGlobalAnsi(str1);var ptr2 = AoTHelp.Combine(ptr1, 500);var str2 = Marshal.PtrToStringAnsi(ptr2);AoTHelp.Free(ptr2);MessageBox.Show($"Hello, World! {sum}  {str2}");}}public static class AoTHelp{[DllImport("AoT001.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]public static extern int Add(int a, int b);[DllImport("AoT001.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]public static extern IntPtr Combine(IntPtr str, int sum);[DllImport("AoT001.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]public static extern void Free(IntPtr ptr);}
}

点击按钮界面如下:

在AoT库中引入MathNet.Numerics库,测试使用三方库后AoT创建dll的情况,新增函数:

        [UnmanagedCallersOnly(EntryPoint = "UseThirdLibTest")]public static bool UseThirdLibTest(int a, int b){var D = Matrix<double>.Build.Dense(2, 9, 1);Console.WriteLine(D);return MathNet.Numerics.Control.Equals(a, b);}

重新发布后dll拷贝到调用项目的debug子命令,dll大下从1.3M变为1.8M。调用代码如下:

        [DllImport("AoT001.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]public static extern bool UseThirdLibTest(int a, int b);private void button2_Click(object sender, EventArgs e){var res = AoTHelp.UseThirdLibTest(100, 100);MessageBox.Show(res.ToString());}

AoT库中传递结构体,AoT定义及调用分别如下:

    [StructLayout(LayoutKind.Sequential, Pack = 8)]public struct ParamStruct{public Int32 ResFlag;public UInt32 a;public UInt32 b;public UInt32 c;}[UnmanagedCallersOnly(EntryPoint = "GetValueFromAoT")]public static ParamStruct GetValueFromAoT(int initValue, ParamStruct param){var result = new ParamStruct();if (initValue < 0){result.ResFlag = -1;return result;}result.ResFlag = 0;result.a = param.a + (UInt32)initValue;result.b = param.b + (UInt32)initValue * 2;result.c = param.c + (UInt32)initValue * 3;return result;}

    [StructLayout(LayoutKind.Sequential, Pack = 8)]public struct ParamStruct{public Int32 ResFlag;public UInt32 a;public UInt32 b;public UInt32 c;}public static class AoTHelp{[DllImport("AoT001.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]public static extern ParamStruct GetValueFromAoT(int initValue, ParamStruct param);}var param = new ParamStruct { a = 10, b = 20, c = 30};var param2 = AoTHelp.GetValueFromAoT(100, param);MessageBox.Show(param2.ToString());

注:结构体定义内如含bool运行时报错、含数组编译报错,简单的数值类型是ok的。如需要传递字符串,可使用IntPtr来实现。

.Net8的AoT不支持和Ui相关的内容调用,如在库内函数使用Form或MessageBox,看网上介绍.Net9已经支持,有待测试。


http://www.mrgr.cn/news/92817.html

相关文章:

  • 神经网络|(十一)|神经元和神经网络
  • windows本地化部署Dify+Deepseek
  • 【零基础C语言】第三节 控制结构
  • 为AI聊天工具添加一个知识系统 之129 详细设计之70 编程 核心技术:Cognitive Protocol Language 之2
  • CSS—背景属性与盒子模型(border、padding、margin)
  • 如何从零开始理解LLM训练理论?预训练范式、模型推理与扩容技巧全解析
  • Linux——基本指令
  • Spring Boot集成Spring Ai框架【详解 搭建Spring Ai项目,以及简单的ai大模型智能体应用,附有图文+示例代码】
  • ue5 创建多列StreeView的方法与理解
  • 【13】智能合约进阶
  • RabbitMQ快速入门
  • 【Python 语法】算法合集
  • HTMLS基本结构及标签
  • 分享一套适合做课设的SpringBoot商城系统
  • React底层原理详解
  • 5分钟看懂Deepseek开源周之六:Deepseek-V3/R1推理系统设计----揭开深度求索模型系统设计和运营成本之谜
  • Linux-ftrace-双nop机制的实现
  • 【异地访问本地DeepSeek】Flask+内网穿透,轻松实现本地DeepSeek的远程访问
  • 10.1 指针进阶
  • 施耐德 PLC 硬件库 DTM 的安装