C#调用C++封装的SDK库(dll动态库)——上

news2024/7/6 17:50:00

C#调用C++封装的SDK库(dll动态库)——上

一、C++封装库

通过前几篇文章,我们封装了C++的动态DLL库,有Qt版的,有C++版的,当然还有介绍了Pimpl模式在SDK封装中的使用:

Qt创建SDK

VS创建SDK

Pimple在SDK封装中的应用

但是,我遇到了一个场景:需要把VS创建的DLL动态库,给C#代码来调用(并且我的动态库中还包含我的计算类)。本篇文章就介绍如何来封装,并提供调用。

 二、C#调用的方式

我们C++的项目里,经常是把算法单独封装为一个类供其他的类来调用的,这样也方便管理,但是如果我们写的这个C++算法类要封装成动态DLL库,供C#代码来调用,这时候就不能直接调用了,我们知道C#和C++时两种语言,要想让C#调用C++的库,这时候只要有个中间桥梁不久可以了。

对于此,微软提供了2种调用dll的方式,托管非托管

对于托管和非托管,可以这样简单的理解托管就是内存管理由系统管理,而不是由程序员自己来管理。而C++本身的内存管理是由程序员来控制的。

C#编写的是托管代码,所以微软提供了托管C++,托管C++用于微软的 Common Language Runtime (CLR) .NET开发,这种特殊的C++语法能够使C++程序员进行.NET开发,而不需要学一门像C#这样的新语言。托管C++和C#的特性一样,只是编程风格与C++类似,这也是微软兼顾不同语言之间的交互而做的。

而使用非托管C++的方法就是使用DllImport的方法来调用,其中DLL文件时用C语言编写的。

本片主要介绍通过非托管的方式封装动态dll库,并使用C#调用

三、封装C语言风格的库

1、我们创建一个DLL的动态库工程,命名CalculationDLL。

 

 

在项目中添加一个Calculation类。

 

 Calculation.h头文件添加如下代码:

#pragma once

#ifdef DLLCALCULATION_EXPORTS
#define DLLCALCULATION_API __declspec(dllexport)
#else
#define DLLCALCULATION_API __declspec(dllimport)
#endif // DLLCALCULATION_EXPORTS


class Calculation
{
};

EXTERN_C DLLCALCULATION_API int add(int a, int b);

EXTERN_C DLLCALCULATION_API int subtract(int a, int b);

EXTERN_C DLLCALCULATION_API int multiply(int a, int b);

EXTERN_C DLLCALCULATION_API int divide(int a, int b);

Calculation.cpp文件添加如下代码:

#include "pch.h"
#include "Calculation.h"

DLLCALCULATION_API int add(int a, int b) 
{
	return (a + b);
}

DLLCALCULATION_API int subtract(int a, int b)
{
	return (a - b);
}

DLLCALCULATION_API int multiply(int a, int b)
{
	return (a * b);
}

DLLCALCULATION_API int divide(int a, int b)
{
	return (a / b);
}

在属性页,C/C++->预处理器->预处理器定义,添加DLLCALCULATION_EXPORTS

 四、创建C#控制台调用

创建一个C#的控制台项目:

 

 

 在Program.cs中输入下面的调用代码:

// See https://aka.ms/new-console-template for more information

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Runtime.InteropServices;

namespace ConsoleApp1
{
    class Program
    {
        [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int add(int a, int b);
                [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int subtract(int a, int b);

        [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int multiply(int a, int b);

        [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int divide(int a, int b);

        static void Main(string[] args)
        {
            int a = 10;
            int b = 2;
           Console.WriteLine("a+b= " + add(a,b) );
            Console.WriteLine("a-b= " + subtract(a, b));
            Console.WriteLine("a*b= " + multiply(a, b));
            Console.WriteLine("a/b= " + divide(a, b));
            Console.WriteLine("calc end.");
            Console.ReadKey();
        }
    }
}

五、运行

运行结果如下:

 

通过以上的过程,我们封装的相当于C语言风格的代码,如果我们要是有个C++的类呢?就像代码中Calculation类,上面是个空类,如果add、subtract等函数时类Calculation的成员函数时,我们该怎么封装呢,你可以思考一下,咱们下一篇继续。

上一篇:VS2022中创建C++SDK库(dll动态库)并调用SDK库(dll动态库)

下一篇:

本文原创作者:冯一川(ifeng12358@163.com),未经作者授权同意,请勿转载。

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

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

相关文章

关于逻辑回归的几个函数

写作业时重新理了下,如果有问题欢迎指正! 说是回归,其实就是个分类,用【0,1】标记结果y是录取还是录取,而影响结果y的就是X(x0,x1,…xn-1)。怎么判断结果y是0还是1用到的是逻辑回归函数(也叫假…

java企业级信息系统开发学习笔记05 初探Spring AOP

文章目录 一、学习目标二、Spring AOP(一)AOP基本含义(二)AOP基本作用(三)AOP和OOP对比(四)AOP使用方式(五)AOP基本概念 三、采用配置方法使用AOP&#xff08…

windows下Tomcat安装

目录 1.安装java环境 2.配置Tomcat环境变量 3.安装服务 4.启动前修改配置文件 (1)设置tomcat端口 (2)设置临时日志等文件夹的位置 5.放入应用 6.启动Tomcat服务 1.安装java环境 安装tomcat版本对应的JDK 比如:…

Mysql的简介和选择

文章目录 前言一、为什么要使用数据库 数据库的概念为什么要使用数据库二、程序员为什么要学习数据库三、数据库的选择 主流数据库简介使用MySQL的优势版本选择四、Windows 平台下安装与配置MySQL 启动MySQL 服务控制台登录MySQL命令五、Linux 平台下安装与配置MySQL总结 前言…

Redis 分布式锁解决方案

1 背景 我们日常在电商网站购物时经常会遇到一些高并发的场景,例如电商 App 上经常出现的秒杀活动、限量优惠券抢购,还有我们去哪儿网的火车票抢票系统等,这些场景有一个共同特点就是访问量激增,虽然在系统设计时会通过限流、异步…

设计模式:行为型模式 - 责任链模式

文章目录 1.概述2.结构3.案例实现4.优缺点5.源码解析 1.概述 在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有部门负责人、副总经…

链表方式实现栈和队列(C语言)

目录 栈 队列 栈 栈(Stack)是一种常见的数据结构,它是一种线性数据结构,具有后进先出(Last In First Out, LIFO)的特点。栈可以看作是一个容器,只能在容器的一端进行插入和删除操作&#xff0c…

【12 Filter 学习笔记】

Filter 笔记记录 1. Filter 过滤器2. Filter介绍3. FilterChain3. Filter 过滤器的使用4. 过滤器使用细节5. Filter的声明周期6. FilterConfig7. 过滤器五种拦截行为 1. Filter 过滤器 2. Filter介绍 3. FilterChain 3. Filter 过滤器的使用 import javax.servlet.ServletExcep…

SQL:group by 的用法及其与 over(partition by)的区别

1.group by的作用 根据一定的规则将一个数据集划分成若干个小区域,然后针对每个区域进行数据处理。即分组查询,一般是和聚合函数配合使用。 重点说明(重要): 如果用Select选择某个字段,那么这个字段要么在G…

cpld 模拟iic 访问原理实现

1,因为 单片机访问sfp和ds125占用了6路iic,但是现在还有lm75需要使用iic访问,所以要么使用iic片选,但是扩展iic需要的总线不多,这里要么考虑使用互斥锁,也就是使用同一路iic时候加锁,使用完成后就释放。也可以考虑使用cpld模拟iic来访问lm75。 2,cpld 软件模拟iic总线原理…

初识MySql数据库

​​​​使用MySql数据库的英文打字小游戏: 英文打字小游戏 MySql学习 1:MySql是关系型数据库,跨平台的。Sql Server是微软出的啊。 2:Web服务器端运行原理图。 Web服务器:网页资源的获取 游戏服务器:游戏数据的同步…

WEB通讯技术。前端实现SSE长连接,nodejs+express搭建简单服务器,进行接口调试,通过curl请求数据

描述 长连接(Keep-Alive)是一种HTTP/1.1的持久连接技术,它允许客户端和服务器在一次TCP连接上进行多个HTTP请求和响应,而不必为每个请求/响应建立和断开一个新的连接。长连接有助于减少服务器的负载和提高性能。 长连接的HTTP请…

《Android性能优化》一次失败的启动速度优化

正文 在优化APP启动之前,我们首先需要知道,APP启动时究竟发生了什么,才能有的放矢的优化。 APP的启动过程 APP的启动过程就是指,在手机屏幕上点击某个APP的图标,到APP的首页显示在用户面前的过程。 一般APP的启动过…

Web自动化测试简介及web自动化测试实战交教程

一、认识web自动化测试 1.什么是自动化测试? 自动化测试的概念: 软件自动化测试就是通过测试工具或者其他手段,按照测试人员的预定计划对软件产品进行自动化测试,他是软件测试的一个重要组成部分,能够完成许多手工测试无法完成或…

Linux网络服务----ftp

文章目录 一 、什么是FTP1.1 Standard模式(主动模式)1.2 Passive模式(被动模式) 二 、FTP的作用及工作原理2.1 FTP的作用和模式以及通信方式2.2 FTP的工作原理 三、搭建和配置FTP服务3.1 设置匿名用户访问的FTP服务(最大权限)3.2 …

优化改进YOLOv5算法之添加Res2Net模块(超详细)

目录 1 Res2Net 2 YOLOv5中添加Res2Net block 2.1 common.py配置 2.2 yolo.py配置 2.3.3 创建添加Res2Net block模块的YOLOv5的yaml配置文件 1 Res2Net 关于代表性计算机视觉任务的进一步消融研究和实验结果,即目标检测,类激活 mapping和显著目标检…

设计模式:行为型模式 - 观察者模式

文章目录 1.概述2.结构3.案例实现4.优缺点5.使用场景6.JDK中提供的实现 1.概述 定义: 又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对…

GEE:图像表达式计算——ee.Image.expression()详解

作者: _养乐多_ 在遥感图像处理和分析中,图像的表达式计算是一种常见的操作。利用 Google Earth Engine(GEE)平台的强大功能,可以方便地进行基于图像的表达式计算,从而实现对图像进行灵活、高效的处理和分析。 本文将介绍 GEE 平台中的 ee.Image.expression() 函数及其参…

Linux的虚拟地址空间与文件描述符

虚拟地址空间与文件描述符 虚拟地址空间文件描述符 虚拟地址空间 文件描述符

SAS学习第9章:卡方检验之适和性检验与独立性检验

卡方检验就是统计样本的实际观测值与理论推断值之间的偏离程度,实际观测值与理论推断值之间的偏离程度就决定卡方值的大小,如果卡方值越大,二者偏差程度越大;反之,二者偏差越小;若两个值完全相等时&#xf…