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

news2024/11/13 22:30:39

.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函数的地址并赋值给pAdd

	int a = 1, b = 2;
	int c = pAdd(a, b); // 显式地通过pAdd指针来调用从DLL中导出的add函数
}

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

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

相关文章

多层、六边形、洋葱和clean架构简介

想想回到过去的美好时光&#xff0c;根本没有所谓架构&#xff0c;那些日子是多么幸福啊&#xff0c;只有了解 GoF 模式&#xff0c;你就能称自己为架构师。 然而&#xff0c;计算机变得更加强大&#xff0c;用户的需求增加&#xff0c;导致应用程序的复杂性增加。 开发人员解决…

一场内容生产的革命 :从PGC、UGC到AIGC

1 概念解读 1.1 什么是PGC&#xff1f; PGC 是指专业生成内容&#xff08;Professional Generated Content&#xff09;&#xff0c;是由专业的内容创作者或团队进行创作、编辑和发布的内容。PGC创作方式起源于传统媒体时代&#xff0c;如报纸、杂志、电视和电影等&#xff0…

低代码技术在各大行业中的应用探讨

随着低代码开发平台的兴起&#xff0c;越来越多的企业开始探索和采用这一技术&#xff0c;以加速应用程序的开发和数字化转型。低代码开发平台的优势在于简化和加速开发过程&#xff0c;降低了技术门槛&#xff0c;使得非专业开发人员也能参与应用程序的创建。在本篇文章中&…

Linux下挂载NFS服务

描述&#xff1a;在Linux下把文件挂在到Linux开发板中实现文件共享 准备步骤&#xff1a;Ubuntu和一块Linux开发板 网络环境&#xff1a;确保在同一个网段&#xff1a;例如192.168.1.226 和192.168.3.226 是不同的网段 NFS介绍 网络文件系统&#xff0c;英文 Network File …

Linux上安装和使用SSH工具

文章目录 前言一、安装SSH Server1. 安装ssh安装包2. 启动ssh3. 设置ssh开机启动 二、 检查SSH状态三、备注 前言 SSH&#xff08;Secure Shell&#xff0c;安全外壳&#xff09;是一种网络安全协议&#xff0c;通过加密和认证机制实现安全的访问和文件传输等业务&#xff0c;…

MySQL 的全局锁、表锁和行锁

在前一篇文章我讲了下 MySQL 的全局锁、表记锁和行级别锁&#xff0c;其中行级锁只提了概念&#xff0c;并没有具体说。 因为行级锁加锁规则比较复杂&#xff0c;不同的场景&#xff0c;加锁的形式还不同&#xff0c;所以这次就来好好介绍下行级锁。 对记录加锁时&#xff0c;加…

PyTorch模型安卓部署流程(NCNN)

上一篇介绍了PyTorch模型部署流程&#xff08;Onnx Runtime&#xff09;的相关部署流程,再来简单的回顾一下~ 深度学习模型部署介绍 模型部署指让训练好的深度学习模型在特定环境中运行的过程。模型部署会面临的难题&#xff1a; 运行模型所需的环境难以配置。深度学习模型通…

驱动设备的IOCTL

一、ioctl操作实现 已知成员的地址获得所在结构体变量的地址&#xff1a; container_of(成员地址,结构体类型名&#xff0c;成员在结构体中的名称) long xxx_ioctl (struct file *filp, unsigned int cmd, unsigned long arg); 功能&#xff1a;对相应设备做指定的控制操作&…

GB28181设备接入侧录像查询和录像下载技术探究之实时录像

技术背景 我们在对接GB28181设备接入侧的时候&#xff0c;除了常规实时音视频按需上传外&#xff0c;还有个重要的功能&#xff0c;就是本地实时录像&#xff0c;录像后的数据&#xff0c;在执法记录仪等前端设备留底&#xff0c;然后&#xff0c;到工作站拷贝到专门的平台。 …

订单系统、报名、预约、表单系统 定制开发功能展示

安装教程环境说明&#xff1a;正常情况下PHP5.3-5.6、阿帕奇、mysql安装即可 安装说明&#xff1a; 1、上传源码压缩包到网站根目录&#xff08;这个请去问下空间商哪个是根目录&#xff0c;每家服务器商不一样&#xff0c;我们也不能确定&#xff0c;请确定是根目录再安装&am…

Java设计模式之行为型-解释器模式(UML类图+案例分析)

目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 五、总结 一、基础概念 解释器模式是指给定一个语言&#xff08;表达式&#xff09;&#xff0c;来表示它的文法&#xff0c;并定义一个解释器&#xff0c;使用该解释器来解释语言中的句子&#xff08;表达式&a…

Linux基础内容(25)—— 线程控制和线程结构

Linux基础内容&#xff08;24&#xff09; —— 线程概念_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/131294692?spm1001.2014.3001.5501 目录 1.线程操作 1.线程创建问题 2.线程终止问题 1.exit退出 2.pthread_exit退出 3.直接退出 3…

只需一个提示词解除GPT-4的字符限制!

ChatGPT的内存有限,GPT-3.5-turbo的限制为4897个令牌,而GPT-4的最大限制为8192。如果您在使用GPT-4进行聊天时超过8192个令牌(约6827个单词),它就会开始遗忘。我想出了一种新的技巧,可以轻松将对话扩展10倍。 这种技巧不会将对话中的每个字都保存到内存中。当您去开会时,会有人…

0502事务原理-InnoDB引擎-MySQL-数据库

1 概述 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有操作作为一个整体一起向系统提交或者撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 事务特性 原子性&#xff08;Atomatic&#xff09;&#xff1a;事…

MiniGPT4系列之一部署篇:在RTX-3090 Ubuntu服务器部署步骤详解

MiniGPT4系列之一部署篇&#xff1a;在RTX-3090 Ubuntu服务器部署步骤详解_seaside2003的博客-CSDN博客 MiniGPT4系列之二推理篇命令行方式&#xff1a;在RTX-3090 Ubuntu服务器推理详解_seaside2003的博客-CSDN博客 MiniGPT4系列之三模型推理 (Web UI)&#xff1a;在RTX-309…

外包软件定制开发中关于沟通障碍及对应解决方案

引言 外包软件定制开发在当今的商业环境中越来越常见。它为公司提供了许多好处&#xff0c;包括降低成本、加速交付和专注于核心业务。然而&#xff0c;沟通障碍常常是外包软件定制开发中的一个重要挑战。由于外包团队和客户位于不同的地理位置、文化和语言差异&#xff0c;沟…

Python 列表 sort()函数使用详解

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 sort函数使用详解 1、升序降序2、sort()和sorted()的区别3、切片排序4、指定排序…

【C++】设计模式-单例模式

目录 一、单例模式 单例模式的三个要点 针对上述三要点的解决方案 常用的两类单例模式 二、懒汉模式实现 1.基本实现 2.锁静态成员析构单例 3.双层检查锁定优化 4.双层检查锁定智能指针 三、饿汉模式实现 1.基础实现 2.嵌套内部类解决内存泄漏 3.智能指针解决内存泄…

一种用于RBF神经网络的新型自适应内核研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

vuejs源码之虚拟dom中的vnode

在虚拟dom中&#xff0c;vnode是比较重要的。 什么是vnode 在vuejs中&#xff0c;有一个Vnode类 使用它可以实例不同类型的vnode实例&#xff0c;而不同类型的vnode实例各自表示不同类型的dom元素。 例如dom元素有文本节点&#xff0c;元素节点&#xff0c;注释节点等。 co…