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

news2024/9/22 3:40:05

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

一、说明

上一篇我们相当于封装的是C语言风格的动态dll库,供C#来调用的。

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

如果我们要封装的是下面的类呢?我们该怎么办?大家先思考下。


class Calculation
{
public:
    Calculation();

    int add(int a, int b);
 
    int subtract(int a, int b);
 
    int multiply(int a, int b);
 
    int divide(int a, int b);
    
};
 

 二、思路

不知道大家还记得设计模式中的单例模式吗?

我们可以采用类似的处理方式,通过创建一个实例函数指针的方式,来通过这个实例作为一个参数来调用累的成员函数。

如下所示:

Calculation* getCalculation();
int add(Calculation* pCalculation, int a, int b);

三、创建动态DLL

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
{
public:
    Calculation();

    int add(int a, int b);
 
    int subtract(int a, int b);
 
    int multiply(int a, int b);
 
    int divide(int a, int b);
    
};

EXTERN_C DLLCALCULATION_API Calculation* getCalculation();

EXTERN_C DLLCALCULATION_API void destructorCalculation(Calculation* pCalculation);
 
EXTERN_C DLLCALCULATION_API int add(Calculation* pCalculation, int a, int b);
 
EXTERN_C DLLCALCULATION_API int subtract(Calculation* pCalculation, int a, int b);
 
EXTERN_C DLLCALCULATION_API int multiply(Calculation* pCalculation, int a, int b);
 
EXTERN_C DLLCALCULATION_API int divide(Calculation* pCalculation, int a, int b);

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

#include "pch.h"
#include "Calculation.h"
 
Calculation::Calculation()
{
}

int Calculation::add(int a, int b) 
{
	return (a + b);
}
 
int Calculation::subtract(int a, int b)
{
	return (a - b);
}

int Calculation::multiply(int a, int b)
{
	return (a * b);
}
 
int Calculation::divide(int a, int b)
{
	return (a / b);
}

DLLCALCULATION_API Calculation* getCalculation()
{
    return new Calculation();
}

DLLCALCULATION_API void destructorCalculation(Calculation* pCalculation)
{
    if( pCalculation )
    {
        delete pCalculation;
        pCalculation = NULL;
    }
}
 
DLLCALCULATION_API int add(Calculation* pCalculation, int a, int b)
{
    return pCalculation->add(a,b);
}
 
DLLCALCULATION_API int subtract(Calculation* pCalculation, int a, int b)
{
    return pCalculation->subtract(a,b);
}
 
DLLCALCULATION_API int multiply(Calculation* pCalculation, int a, int b)
{
    return pCalculation->multiply(a,b);
}
 
DLLCALCULATION_API int divide(Calculation* pCalculation, int a, int b)
{
    return pCalculation->divide(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 IntPtr getCalculation();
                [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static void destructorCalculation(IntPtr pCalculation);
        [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int add(IntPtr pCalculation, int a, int b);
                [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int subtract(IntPtr pCalculation, int a, int b);
 
        [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int multiply(IntPtr pCalculation, int a, int b);
 
        [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int divide(IntPtr pCalculation, int a, int b);
 
        static void Main(string[] args)
        {
            IntPtr pCalculation = getCalculation();
            
            int a = 10;
            int b = 2;
            Console.WriteLine("a+b= " + add(pCalculation, a, b));
            Console.WriteLine("a-b= " + subtract(pCalculation, a, b));
            Console.WriteLine("a*b= " + multiply(pCalculation, a, b));
            Console.WriteLine("a/b= " + divide(pCalculation, a, b));
            
            destructorCalculation(pCalculation);

            Console.WriteLine("calc end.");
            Console.ReadKey();
        }
    }
}

好了,你可以运行看看效果了。

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

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

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

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

相关文章

Tomcat常用操作

Tomcat时间长不用,居然不会用了,这里用的Tomcat9.0.74,对应的jdk版本是jdk8与jdk11。 先看他的把Tomcat安装上去:Tomcat9的安装 运行与关闭Tomcat winr输入cmd。在运行窗口输入startup.bat,回车,启动Tom…

Java基础:对象的克隆(复制)

假如想复制一个简单变量。很简单: int apples 5; int pears apples; 不仅int类型,其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况。 但是如果你复制的是一个对象,情况就复杂了。 假设说我是一个b…

webpack----开发服务器

文章目录 devServer抽取csscss的兼容性压缩cssjs语法检查js的兼容性 devServer 每次编辑源码后,都要webpack重新打包,才能看到效果,麻烦!使用webpack-dev-server 自动打包编译源码配置 // webpack.config.js ... mode: "de…

shell中的for循环和if判断

一.编写脚本for1.sh,使用for循环创建20账户,账户名前缀由用户从键盘输入,账户初始密码由用户输入,例如: test1、test2、test3、.....、 test10 1.创建脚本for1.sh [rootserver ~]# vim for1.sh 2.编写脚本for1.sh 3.执行脚本for1.sh [roo…

linux命令----- mkdir与rmdir

创建与删除目录 一 mkdir1.mkdir 目录名2.mkdir -p 目录一/目录二 二 rmdir1.rmdir 目录名2.删除非空目录时失败3. rmkdir -p 目录1/目录2 一 mkdir mkdir是make directories的缩写,主要用于linux中创建目录 创建的目录不能和同级目录中已经存在的目录重名可以mkd…

【产品经理】系统上线自查清单

产品上线之前的准备工作,看起来简单,实际做起来是非常繁杂的,如果没有尽早考虑和准备,可能会手忙脚乱甚至导致产品延迟上线。 产品上线前的准备工作听起来简单,但实际做起来非常繁杂。除了要考虑用户需求、商业需求外&…

计算广告(十八)

营销组合模型 MMM 分析背景 随着媒体类型和销售渠道的不断变化,客户旅程日益复杂化。单一活动层面的优化已无法满足客户需求。为了应对这一挑战,品牌方需在战略和活动层面构建完整的营销视图,优化各营销渠道间的效率并实现最高投资回报率。…

【BIM+GIS】ArcGIS Pro3.0打开多种格式三维模型案例教程

本文讲解在ArcGIS Pro3.0打开BIM模型(.rvt)、倾斜模型OSGB、Sketchup(.skp)、3d max(.3ds)、点云数据(.las)的方法及注意事项。 文章目录 一、ArcGIS Pro打开BIM(.rvt)二、ArcGIS Pro打开倾斜OSGB三、ArcGIS Pro打开Sketchup(.skp)四、ArcGIS Pro打开3d max(.3ds)…

C++ [模板]

本文已收录至《C语言》专栏! 作者:ARMCSKGT 目录 前言 正文 泛型编程 问题引入 泛型 函数模板 概念 格式 使用方式 模板原理 模板的实例化 隐式实例化 显示实例化 模板匹配规则 类模板 类模板定义格式 类模板的实例化 非类型模板参数 …

【13 Listener 学习笔记】

Listener 笔记记录 1. Listener监听器2. 监听对象的监听器2.1 ServletContetListener2.2 HttpSessionListener2.3 ServletRequestListener 3. 监听域对象属性变化的监听器3.1 ServletContextAttributeListener3.2 HttpSessionAttributeListener3.3 ServletRequestAttributeList…

每日一个小技巧:如何去水印而不损图片?赶紧学起来

在数码时代中,照片的处理与分享已经成为了我们日常中不可或缺的一部分。但是,大家在网上保存的图片常常会带有水印,非常影响图片的观赏性。水印旨在防止照片被盗用或侵权,但有时候它也很破坏照片的美感,因此许多人都在…

超级实用的C++学习网站

重要说明:该博客长期更新,方便读者查阅! 一、参考资料 学习C这几个网站足矣 二、C学习网站 C中文网 cppreference 当之无愧的C学习第一网站。该网站希望给程序员提供一个关于C和C的完整的在线参考,所以它的内容非常的丰富。有…

动态类型语言、静态类型语言、强类型语言、弱类型语言解释

首先要明确这些名词都是针对数据类型展开的各自定义,同样针对数据类型在编译时和运行时会有一些限定或者规则存在。动态类型语言不能等同于弱类型语言,静态类型语言也不能等同于强类型语言。 静态类型语言和动态类型语言放到一个维度来进行评价类型系统&…

ClickHouse物化视图

目录 1 概述1.1 物化视图与普通视图的区别1.2 优缺点1.3 基本语法 2 案例实操2.1 准备测试用表和数据2.2 创建物化视图2.3 导入增量数据2.4 导入历史数据 1 概述 ClickHouse 的物化视图是一种查询结果的持久化,它确实是给我们带来了查询效率的提升。用户查起来跟表没…

MYSQL---主从同步概述与配置

一、MYSQL主从同步概述 1、什么是MySQL主从同步? 实现数据自动同步的服务结构 主服务器(master): 接受客户端访问连接 从服务器(slave):自动同步主服务器数据 2、主从同步原理 Maste:启用binlog 日志 Slave:Slave_IO: 复制master主…

CPU寄存器的分类与Intel 8086 的eax,ebx,ecx,edx

目录 一、CPU中的寄存器分类 1.用户可见寄存器 2.控制和状态寄存器 一、CPU中的寄存器分类 大致分为两类: 一类属于用户可见寄存器,对这类寄存器编程,以及通过优化使CPU因使用这类寄存器,而减少对主存的访问次数, 另一类属于控…

MPRC086444-005对其进行维护和管理,以确保系统的稳定性和可靠性。

​ MPRC086444-005对其进行维护和管理,以确保系统的稳定性和可靠性。 变电站自动化系统优缺点 变电站自动化系统结构 变电站自动化系统优缺点 变电站自动化系统是以计算机技术、自动控制技术及通信技术为核心,对变电站及配电系统各个环节进行自动化控制和…

自动化生成持久化游戏管理器

自动化生成持久化游戏管理器 引言游戏管理器持久化自动化生成游戏管理器Addressables 引言 自动化生成的持久化游戏管理器是一个指通过使用自动化工具和技术来生成游戏的持久化管理器的过程。持久化管理器是负责管理游戏状态的组件,包括存储和检索游戏数据的功能&a…

GPT3 和它的 In-Context Learning

作者 | 太子长琴 整理 | NewBeeNLP 大家好,这里是NewBeeNLP。ChatGPT 的爆火让很多 NLPer 大吃一惊,焦虑感爆棚,它的思路和方法都不复杂,但效果却出奇的好。 我想任何研究成果的爆发都不可能是一蹴而就的,期间必然包含…

【历史上的今天】4 月 18 日:第一款交互式电子游戏;IBM 率先研发兆位芯片;硬件公司 Roland 成立

整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来。 今天是 2023 年 4 月 18 日,在 1955 年的今天,著名物理学家爱因斯坦在美国新泽西州的普林斯顿逝世。爱因斯坦于 1905 年获得物理学博士学位&#xff0c…