使用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.mzph.cn/diannao/72338.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Goby 漏洞安全通告| Ollama /api/tags 未授权访问漏洞(CNVD-2025-04094)

漏洞名称&#xff1a;Ollama /api/tags 未授权访问漏洞&#xff08;CNVD-2025-04094&#xff09; English Name&#xff1a;Ollama /api/tags Unauthorized Access Vulnerability (CNVD-2025-04094) CVSS core: 6.5 风险等级&#xff1a; 中风险 漏洞描述&#xff1a; O…

端到端自动驾驶——cnn网络搭建

论文参考&#xff1a;https://arxiv.org/abs/1604.07316 demo 今天主要来看一个如何通过图像直接到控制的自动驾驶端到端的项目&#xff0c;首先需要配置好我的仿真环境&#xff0c;下载软件udacity&#xff1a; https://d17h27t6h515a5.cloudfront.net/topher/2016/November…

蓝桥杯试题:二分查找

一、问题描述 给定 n 个数形成的一个序列 a&#xff0c;现定义如果一个连续子序列包含序列 a 中所有不同元素&#xff0c;则该连续子序列便为蓝桥序列&#xff0c;现在问你&#xff0c;该蓝桥序列长度最短为多少&#xff1f; 例如 1 2 2 2 3 2 2 1&#xff0c;包含 3 个不同的…

网络空间安全(7)攻防环境搭建

一、搭建前的准备 硬件资源&#xff1a;至少需要两台计算机&#xff0c;一台作为攻击机&#xff0c;用于执行攻击操作&#xff1b;另一台作为靶机&#xff0c;作为被攻击的目标。 软件资源&#xff1a; 操作系统&#xff1a;如Windows、Linux等&#xff0c;用于安装在攻击机和…

DeepSpeek服务器繁忙?这几种替代方案帮你流畅使用!(附本地部署教程)

作者&#xff1a;后端小肥肠 目录 1. 前言 2. 解决方案 2.1. 纳米AI搜索&#xff08;第三方平台&#xff09; 2.2. Github&#xff08;第三方平台&#xff09; 2.3. 硅基流动&#xff08;第三方API&#xff09; 3. 本地部署详细步骤 3.1. 运行配置需求 3.2. 部署教程 4…

prisma+supabase报错无法查询数据

解决方案&#xff0c;在DATABASE_URL后面增加?pgbouncertrue

c语言中return 数字代表的含义

return 数字的含义&#xff1a;表示函数返回一个整数值&#xff0c;通常用于向调用者&#xff08;如操作系统或其他程序&#xff09;传递程序的执行状态或结果。 核心规则&#xff1a; return 0&#xff1a; 含义&#xff1a;表示程序或函数正常结束。 示例&#xff1a; int m…

Spark内存迭代计算

一、宽窄依赖 窄依赖&#xff1a;父RDD的一个分区数据全部发往子RDD的一个分区 宽依赖&#xff1a;父RDD的一个分区数据发往子RDD的多个分区&#xff0c;也称为shuffle 二、Spark是如何进行内存计算的&#xff1f;DAG的作用&#xff1f;Stage阶段划分的作用&#xff1f; &a…

Linux知识-第一天

Linux的目录机构为一个树型结构 其没有盘符这个概念&#xff0c;只有一个根目录&#xff0c;所有文件均在其之下 在Linux系统中&#xff0c;路径之间的层级关系 使用 / 开头表示根目录&#xff0c;后面的表示层级关系 Linux命令入门 Linux命令基础 Linux命令通用格式 comman…

QT实现单个控制点在曲线上的贝塞尔曲线

最终效果: 一共三个文件 main.cpp #include <QApplication> #include "SplineBoard.h" int main(int argc,char** argv) {QApplication a(argc, argv);SplineBoard b;b.setWindowTitle("标准的贝塞尔曲线");b.show();SplineBoard b2(0.0001);b2.sh…

绘制思维导图画布选型

在实现思维导图/知识图谱的绘制时&#xff0c;选择合适的「画布」技术方案至关重要。以下是不同技术路线的对比分析和推荐方案&#xff1a; 一、技术方案对比 技术类型实现方式优点缺点适用场景普通DOM元素使用<div>CSS布局&#x1f539; 开发简单&#x1f539; 天然支持…

运维Splunk面试题及参考答案

目录 通过转发器导入数据的优势有哪些(如带宽控制、负载均衡等) 描述 Universal Forwarder 与 Heavy Forwarder 的差异 如何配置转发器实现数据的过滤与预处理 转发器的本地缓存机制如何保证数据可靠性 如何通过部署服务器统一管理多个转发器的配置 什么是 “查找表(L…

年后寒假总结及计划安排

年后寒假总结 年后主要学习了微服务&#xff0c;nacos (服务注册中心)&#xff0c;feign&#xff08;远程调用&#xff09;&#xff0c;网关&#xff0c;双token&#xff08;相较于之前更加规范&#xff0c;更加符合企业级&#xff09;&#xff0c;配置管理 &#xff0c;mybati…

word中交叉引用多篇参考文献格式[1-2]或[1-4]操作

划重点 更改左域名&#xff0c;输入 \#"[0" 更改中间域名&#xff0c;输入\#"" 更改右域名&#xff0c;输入 \#"0]" 1.[2-3]格式 首先点击交叉引用&#xff0c;引用参考文献 右击鼠标&#xff0c;点击切换域代码&#xff0c;对于左域名 删除 * …

【银河麒麟高级服务器操作系统】服务器测试业务耗时问题分析及处理全流程分享

更多银河麒麟操作系统产品及技术讨论&#xff0c;欢迎加入银河麒麟操作系统官方论坛 https://forum.kylinos.cn 了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer…

opencv 模板匹配方法汇总

在OpenCV中&#xff0c;模板匹配是一种在较大图像中查找特定模板图像位置的技术。OpenCV提供了多种模板匹配方法&#xff0c;通过cv2.matchTemplate函数实现&#xff0c;该函数支持的匹配方式主要有以下6种&#xff0c;下面详细介绍每种方法的原理、特点和适用场景。 1. cv2.T…

NAT,代理服务,内网穿透

NAT 把报文的源IP替换为途径路由器的WAN口IP NAPT 如何将数据从公网转回给内网的主机&#xff1f;通过NAPT&#xff08;转换表&#xff09;来实现&#xff0c;每次从内网到公网&#xff0c;公网到内网都会根据转换表来进行 细节&#xff1a; NAT转换时&#xff0c;值替换源…

大模型分布式训练和优化

1. 分布式训练概述 随着语言模型参数量和所需训练数据量的急速增长,单个机器上有限的资源已无法满足大语言模型训练的要求。因此,设计分布式训练(Distributed Training)系统来解决海量的计算和内存资源需求问题变得至关重要。 分布式训练是指将机器学习或深度学习模型训练任…

第三方机构有哪些接口?

1&#xff0c;网银接口。2&#xff0c;代扣接口。3&#xff0c;POS接口。4&#xff0c;快捷支付接口 1.网银接口 第三方支付平台连接网银接口&#xff0c;进行支付跳转时&#xff0c;第三方支付平台充当了一个网关的角色&#xff0c;或者充当了银行的代 理。 2.代扣接口 银…

JUnit 版本影响 Bean 找不到

JUnit 版本影响 Bean 找不到 在为实现类编写测试类时&#xff0c;在测试类中使用构造器注入 Bean 时&#xff0c;提示找不到 Bean&#xff0c;代码如下&#xff1a; Service public class WeChatServiceImpl implements IWeChatService {Overridepublic String getNumber(Str…