.NET Native AOT的静态库与动态库

.NET不仅可以使用 C静态库与动态库,也可以将.NET实现的函数导出为C静态库与动态库。在没有Native Aot之前,.NET只能通过P/Invoke享受C/C++生态,而在Native Aot之后,不仅可以享受这些生态,还可以开发SDK供其他语言调用。

.NET Native AOT的NativeLib参数用于指定本机库的类型。在.NET 7中,该参数有两个选项:Static和Shared。

  • Static: 生成静态库,意味着所有依赖项都将被编译到生成的可执行文件中,因此它更适合独立应用程序或需要最小化依赖项的应用程序。
  • Shared: 生成动态库,意味着依赖项将被编译为单独的本机库,并在运行时动态加载。这种方法可以减少生成文件大小,并且更适合需要共享依赖项的应用程序,所以它也被称为共享库。

使用UnmanagedCallersOnly特性可以将C#函数导出提供给C调用,EntryPoint属性用于指定导出的方法名称。

.NET函数导出

使用UnmanagedCallersOnly特性可以将C#函数导出提供给C调用,EntryPoint属性用于指定导出的方法名称。

public static class MyFunctions
{[UnmanagedCallersOnly(EntryPoint = "Add")]public static int Add(int a, int b){return a + b;}[UnmanagedCallersOnly(EntryPoint = "PrintString")]public static void PrintString(IntPtr str){Console.WriteLine(Marshal.PtrToStringAnsi(str));}[UnmanagedCallersOnly(EntryPoint = "GetSystemInfoWrite")]public static void GetSystemInfo(){Console.WriteLine($"ProcessorCount: {Environment.ProcessorCount}");Console.WriteLine($"MachineName: {Environment.MachineName}");}}

在项目属性中加入PublishAot即可:

<PropertyGroup><PublishAot>true</PublishAot>
</PropertyGroup>

您可以使用以下命令来指定NativeLib参数:

dotnet publish -r win-x64 -c release /p:NativeLib=Static

dotnet publish -r win-x64 -c release /p:NativeLib=Shared

通过JetBrains dotPeek工具查看DLL文件中是否包含导出的几个函数:

在C++中使用Native dll

在C++中调用DLL函数也可以分为隐式调用和显式调用两种方式。

隐式调用

附加库目录---添加文件引用的lib动态库路径:

项目->属性->配置属性->链接器->常规->附加库目录:加上lib文件的存放目录;

附加依赖项---添加工程引用的lib文件名:

项目->属性->配置属性->链接器->输入->附加依赖项:加上lib文件名。

隐式调用是指在代码中直接使用函数名进行调用,而编译器会自动根据参数类型匹配合适的函数。

例如:

#include <iostream>
extern "C"
{typedef int(AddFunc)(int, int);typedef void(PrintStringFunc)(const char*);typedef void(GetSystemInfoWriteFunc)();__declspec(dllimport) AddFunc Add;__declspec(dllimport) PrintStringFunc PrintString;__declspec(dllimport) GetSystemInfoWriteFunc GetSystemInfoWrite;
}int main()
{int result = Add(1, 2);std::cout << "Result: " << result << std::endl;PrintString("Hello, world!");GetSystemInfoWrite();return 0;
}

随后编译项目,运行C++应用程序即可,如下所示。

Result: 3
Hello, world!
ProcessorCount: 12
MachineName: DESKTOP-MJL9J4R

显式调用

显式调用是指在代码中通过函数指针或者GetProcAddress等API来获取DLL中导出函数的地址,并通过该地址来进行调用。

  • 加载 DLL 文件并返回句柄:HMODULE hDll = LoadLibraryA(PathToLibrary);
  • 获取 DLL 中导出函数地址并赋值给指针变量:AddFunc pAdd = (AddFunc)GetProcAddress(hDll, "Add");
  • 显式地通过指针变量来调用从 DLL 中导出的 add 函数:int c = pAdd(a,b);

例如:

#include <windows.h>
#define PathToLibrary "C:\\Users\\hueifeng\\OneDrive\\InteropSample\\dotnetSample\\bin\\Release\\net7.0\\win-x64\\native\\dotnetSample.dll"typedef int (*AddFunc)(int, int); // 定义一个函数指针类型int main()
{HMODULE hDll = LoadLibraryA(PathToLibrary); // 加载dotnetSample.dll文件并返回句柄AddFunc pAdd = (AddFunc)GetProcAddress(hDll, "Add"); // 获取Add函数的地址并赋值给pAddint a = 1, b = 2;int c = pAdd(a, b); // 显式地通过pAdd指针来调用从DLL中导出的add函数
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1581.shtml

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

相关文章

WAIC2023会后记

听了3天WAIC的会&#xff0c; 大开眼界&#xff0c;算是上了堂大课。 本次参会的目的是听听AI企业信息化的想法、理论和实践。以进一步探索可能的业务场景。三天的会结束后&#xff0c;留下深刻印象的有如下几点。 大模型当道 2023这次大会的主题成了大模型&#xff0c;谈的…

基于单片机电子密码锁射频卡识别指纹门禁密码锁系统的设计与实现

功能介绍 通过指纹进行开锁或者是按键输入当前的密码&#xff0c;修改密码&#xff0c;对IC卡可以进行注册&#xff0c;删除。当有RFID卡进入到读卡器的读卡范围内时&#xff0c;则会自动读取卡序列号&#xff0c;单片机根据卡的序列号对卡进行判断。若该卡是有效卡&#xff0c…

RabbitMQ安装

这里写目录标题 简介下载ELANG安装ELang配置环境变量安装RabbitMQ 简介 RabbitMQ 是一个开源的遵循 AMQP 协议实现的基于 Erlang语言编写&#xff0c;**即需要先安装部署Erlang环境再安装RabbitMQ环境。**需加注意的是&#xff0c;读者若不想跟着我的版本号下载安装&#xff0…

MacBook Java开发环境搭建记录

一、Homebrew的镜像设置 对于Java JDK的安装&#xff0c;我们更推荐使用Homebrew来进行安装管理。但Homebrew的curl国外源的下载速度实在是一言难尽&#xff0c;时常还会发生无法访问的情况。 那么我们此时的解决方法就有两种了&#xff0c;第一种便是使用全局的VPN代理进行下载…

让你不再疑惑加水印用什么软件

每个人都有自己的独特创意和作品&#xff0c;而在现今互联网时代&#xff0c;分享和传播作品已成为一种普遍现象。然而&#xff0c;随着互联网的发展&#xff0c;越来越多的作品被人恶意盗用和复制&#xff0c;使得原创作者的权益受到了侵害。为了保护自己的作品&#xff0c;加…

【SpringBoot】从零开始封装自己的starter并且引入到其他项目中使用

从零开始封装自己的starter并且引入到其他项目中使用 简介 本文将介绍如何从零开始封装自己的starter并且引入到其他项目中使用 为什么要自己封装starter&#xff1f; 这样可以对spring以及其他第三方提供的starter做二次封装或者封装一些自己需要的内容提供给其他项目使用&…

MySQL五种约束类型(普通 /自增主键,外键等) + 进阶查询(聚合查询,内 /外连接查询,自连接查询,子查询,合并查询)

文章目录 前言一、五种约束NOT NULL 约束UNIQUE 约束DEFAULT 约束PRIMARY KEY 主键约束(重点)普通主键自增主键 FOREIGN KEY 外键约束(重点) 二、进阶查询聚合查询聚合函数GROUP BY子句HAVING 联合查询笛卡尔积内连接外连接自连接子查询单行子查询&#xff1a;返回一行记录的子…

乔云监控tf卡格式化后数据恢复方法

您有没有使用过乔云牌监控设备呢&#xff1f;它通常里面会放置一个TF卡以存储录像&#xff0c;而TF卡长期高温高速运行&#xff0c;容易产生碎片&#xff0c;因此很多商家会建议大家一个月进行一次格式化。但是格式化后您有没有后悔过呢&#xff1f;在这个篇文章中&#xff0c;…

【Python】类型注解 ③ ( 使用 # type: 类型 注释方式设置类型注解 | 类型注解是提示性而非强制性 )

文章目录 一、使用 注释语法 设置 类型注解1、使用 注释语法 设置 类型注解语法介绍2、为 基础类型变量 设置 " 类型注解 "3、为 类 的 对象类型 设置 " 类型注解 "4、为 基础容器类型变量 设置 简易 " 类型注解 "5、为 基础容器类型变量 设置 详…

基于深度学习的高精度工人安全帽检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度工人安全帽检测识别系统可用于日常生活中或野外来检测与定位工人安全帽目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的工人安全帽目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用…

Windows与Linux取证分析

目录 一、电子数据取证基本概念 1.电子取证学 2.常规取证 3.洛卡德物质交换原理 4.电子数据范围 5.电子数据取证的概念和目的 6.电子数据取证过程 二、Linux系统取证 1.基本信息获取 &#xff08;1&#xff09;获取系统基础信息 &#xff08;2&#xff09;用户/用户…

共筑开源新长城 龙蜥社区走进开放原子校源行-清华大学站

6 月 28 日&#xff0c;以“聚缘于校&#xff0c;开源共行”为主题的 2023 年开放原子校源行活动在清华大学成功举行。本次活动由开放原子开源基金会和清华大学共同主办&#xff0c;来自各行业的 22 位大咖共聚校园共话开源。龙蜥社区技术专家边子政受邀进行技术分享&#xff0…

UWB天线设计之一种优化扁平超宽带单极的新方法

文章亮点 一种新颖的方法提出了扁平超宽带单极天线。 通过应用收缩,可以设计具有相同性能的更小的天线作为平面单极天线。 优化结果表明该方法能够设计非常小的天线。 在这项研究中,提出了一种优化扁平超宽带单极天线的新方法。在该方法中,一般性地描述了天线的形状。这种一…

LeetCode141.环形链表

141.环形链表 目录 141.环形链表一、哈希表二、双指针 一、哈希表 最容易想到的方法就是遍历所有节点&#xff0c;每次遍历到一个节点的时候&#xff0c;判断该节点此前是否被访问过 我们可以使用哈希表来存储所有已经访问过的节点 每次到达一个节点&#xff0c;如果该节点已…

Web3时代来临:你准备好了吗?

如果你正在浏览本文&#xff0c;那么很可能你已经是Web3时代的一部分了&#xff0c;或者至少是将要成为其中的一员。因为Web3时代即将来临&#xff0c;它将彻底改变我们对互联网的认识和使用方式。 那么&#xff0c;什么是Web3时代呢&#xff1f;简单来说&#xff0c;它是指基于…

JPA实现多对多关系

本文已收录于专栏 《Java》 目录 概念说明优势利弊实现方式通过两个ManyToMany注解实现类图代码 通过OneToMany和ManyToOne注解实现类图代码 少走弯路总结提升 概念说明 多对多关系是指两个实体之间存在多对多的关联关系。在数据库中&#xff0c;多对多关系无法直接表示&#x…

【树链+EXGCD】杭电多校第一场 A

1001 Hide-And-Seek Game (hdu.edu.cn) 题意&#xff1a; 给定一棵树和两条路径&#xff0c;每条路径都有起点和终点&#xff0c;起始时起点有人&#xff0c;每隔一秒都会往终点走一步&#xff0c;会从起点走向终点再会起点这样不断地周期性地走&#xff0c;让你求一点&#…

UDP-组播,广播

转自&#xff1a;https://www.cnblogs.com/wangzhilei-src/p/15314315.html UDP是面向非连接的协议&#xff0c;它不与对方建立连接&#xff0c;而是直接把数据报发给对方。UDP无需建立类如三次握手的连接&#xff0c;使得通信效率很高。因此UDP适用于一次传输数据量很少、对可…

STM32 HAL库定时器输入捕获SlaveMode脉宽测量

STM32 HAL库定时器输入捕获SlaveMode脉宽测量 SlaveMode模式简介 ✨SlaveMode复位模式&#xff1a;在发生一个触发输入事件时&#xff0c;计数器和它的预分频器能够重新被初始化&#xff1b;同时&#xff0c;如果TIMx_CR1寄存器的URS位为低&#xff0c;还会产生一个更新事件UEV…

Android TextView 在最后一行末尾加图标

当前有个需求.显示一段文本&#xff0c;文本最多显示两行&#xff0c;点击展开后才显示完全。当没有显示完全的时候&#xff0c;需要在文本的第二行末尾显示图标&#xff0c;点击图标和文本&#xff0c;文本展开。难点在于图标需要和第二行文本显示在同一行&#xff0c;高度和文…