文章目录

  • 1 导出C++ 类函数 、导出 C++函数
    • 1.1 .h文件
    • 1.2 .cpp 文件
    • 1.3 C# 调用
  • 2 C++与C#数据类型对应
  • 3 保姆级教程(项目搭建、代码、调用,图文并茂)

1 导出C++ 类函数 、导出 C++函数

C++ 生成动态库.dll 详细教程:
C++ 生成动态库.dll 及 C++调用DLL,及实际项目中的使用技巧
C++ 生成静态库.lib 及 C++调用lib,及实际项目中的使用技巧

1.1 .h文件

#pragma once
#ifndef MATHTEST_H
#define MATHTEST_H//宏定义导出:
#ifndef MATHTEST_ //如果没有定义 MATHTEST_,就定义MATHTEST_API __declspec(dllexport)
#define MATHTEST_API __declspec(dllexport) //导出
#else
#define MATHTEST_API __declspec(dllimport) //导入
#endif//以C方式导出  C++类函数
class MATHTEST_API mathTest
{public:mathTest();int multiply(int a, int b);//乘法int divide(int a, int b);//除法
};//以C方式导出函数
//extern "C",告诉编译器这里是C语言代码//为了使自己建的库可以在 C/C++ 通用调用,使用 __cplusplus ,
//当C++调用代码时,__cplusplus 值为1,声明函数外面就加了一层“extern "C" {}”;
//当C 调用代码时,__cplusplus 值为0,就相当于没有“extern "C" {}”;#ifdef __cplusplus 
extern "C"
{
#endif//以C方式导出  C++类函数MATHTEST_API mathTest* CreateMyClass();MATHTEST_API void DeleteMyClass(mathTest* obj);MATHTEST_API int Cmultiply(mathTest* obj,int num1, int num2);//加法MATHTEST_API int Cdivide(mathTest* obj,  int num1, int num2);//减法//以C方式导出 C++函数MATHTEST_API int Cadd(int a, int b);//加法MATHTEST_API int Csubtract(int a, int b);//减法
#ifdef __cplusplus
}
#endif#endif

1.2 .cpp 文件

#include "mathTest.h"/*创建动态库d11:1.VS创建C++ 空项目MyDLL:编写.h和.cpp文件在.h文件中宏定义导出图数2.生成dll文件:右键项目-->属性-->配置类型-->动态库( .dll)以Debug x64 生成解决方案
*//********************************************* 以C方式导出 C++函数********************************************/
int Cadd(int a, int b)//加法
{return a + b;
}int Csubtract(int a, int b)//减法
{return a - b;
}/********************************************* 以C方式导出 C++类函数********************************************/// 已导出类的构造函数。
mathTest::mathTest()
{return; 
}int mathTest::multiply(int a, int b)//乘法
{return a * b;
}int mathTest::divide(int a, int b)//除法
{return a / b;
}MATHTEST_API mathTest* CreateMyClass()
{return new mathTest();	
}MATHTEST_API void DeleteMyClass(mathTest* obj)
{delete obj;
}
MATHTEST_API int Cmultiply(mathTest* obj, int num1, int num2)//加法
{return obj->multiply(num1,num2);
}
MATHTEST_API int Cdivide(mathTest* obj, int num1, int num2)//减法
{return obj->divide(num1,num2);
}

1.3 C# 调用

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace test
{public partial class Form1 : Form{//extern C ,以C方式导出 C++函数[DllImport("dllTest.dll")]static extern int Cadd(int a, int b);[DllImport("dllTest.dll")]static extern int Csubtract(int a, int b);//extern C ,以C方式导出 C++函数private static IntPtr myClassInstance;  // 定义C++类的实例,用于后面的调用[DllImport("dllTest.dll", CallingConvention = CallingConvention.Cdecl)]private static extern IntPtr CreateMyClass();[DllImport("dllTest.dll", CallingConvention = CallingConvention.Cdecl)]private static extern void DeleteMyClass(IntPtr obj);[DllImport("dllTest.dll", CallingConvention = CallingConvention.Cdecl)]private static extern int Cmultiply(IntPtr obj, int num1, int num2);//加法[DllImport("dllTest.dll", CallingConvention = CallingConvention.Cdecl)]private static extern int Cdivide(IntPtr obj, int num1, int num2);//减法public Form1(){InitializeComponent();}private void button3_Click(object sender, EventArgs e){//以C方式导出 C++函数int Csum = Cadd(10, 5);int Csub = Csubtract(10, 5);string str0 = "动态库测试 dllTest.dll-- 导出 C++函数:";string str1 = "10 + 5 = " + Csum.ToString();string str2 = "10 - 5 = " + Csub.ToString();listBox1.Items.Add(str0);listBox1.Items.Add(str1);listBox1.Items.Add(str2);//以C方式导出 C++ 类函数myClassInstance = CreateMyClass();int Cmul = Cmultiply(myClassInstance, 10, 5);int Cdiv = Cdivide(myClassInstance, 10, 5);str0 = "动态库测试 dllTest.dll--导出 C++ 类函数:";str1 = "10 x 5 = " + Cmul.ToString();str2 = "10 ÷ 5 = " + Cdiv.ToString();listBox1.Items.Add(str0);listBox1.Items.Add(str1);listBox1.Items.Add(str2);// 清理C++内存DeleteMyClass(myClassInstance);}}
}  

在这里插入图片描述

2 C++与C#数据类型对应

C#在调用C++ DLL时,需要通过P/Invoke技术来完成。P/Invoke是.NET Framework用于调用非托管代码库的一种方式。在这个过程中,我们需要处理两种语言之间的数据类型转换,因为它们的数据类型不完全一致。

基本数据类型对应表
以下是C++和C#之间的一些常见数据类型的对应表(请注意,这并不是一个完全的列表,只是一些常见类型的示例):

在这里插入图片描述

3 保姆级教程(项目搭建、代码、调用,图文并茂)

保姆级教程,从C++ 生成动态库.dll 到 C#调用C/C++生成动态库.dll,每一个步骤都非常详细的截图、注释、说明,附原码;

保姆级教程连接:C#调用C/C++生成动态库.dll及C++ 生成动态库.dll ,DllImport()方式导入 C++动态库.dll方法总结

项目下载 :同一个解决方案下多个项目:C++生成动态库项目和C#调用项目

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

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

相关文章

Flutter 与 Android NDK 集成实战:实现高性能原生功能

Flutter 与 NDK 集成实现 Flutter 可以通过 Platform Channels 与原生代码(包括使用 NDK 编写的 C/C 代码)进行交互。以下是实现 Flutter 与 NDK 集成的步骤: 基本步骤 1. 创建 Flutter 项目 flutter create flutter_ndk_example cd flutter_…

elementui cascader 远程加载请求使用 选择单项等

背景:小程序与后端使用自定义表单渲染视图。发现若没有全选(如:省市县全部选择,指定的市3级)在pc端就会无法渲染出已经选择的区县名称。 解决方案:参考官方文档,设置属性可独立勾选element ui c…

Unity WebGL打包后启动方法,本地方法

引言:常见WebGL开启方法常需要重新打包点击Build and Run或者将游戏放到Unity的云服务器上,作为开发者而言这两个方案一个为了开启再次打包,另一个直接放到了公开环境都不太合适。所以我们需要一个能在本地开启测试的WebGL的方法。 解决方案 …

安全引导功能及ATF的启动过程(五)

安全引导功能及ATF的启动过程(五) ATF中bl32的启动 bl31中的runtime_svc_init函数会初始化OP-TEE对应的服务,通过调用该服务项的初始化函数来完成OP-TEE的启动。对于OP-TEE的服务项会通过DECLARE_RT_SVC宏在编译时被存放到rt_svc_des段中。该…

Numpy科学计算与数据分析:Numpy入门之多平台安装与基础环境配置

Numpy环境搭建与基础操作 学习目标 本课程将指导学员在Windows、macOS和Linux三种操作系统上安装Numpy,并配置开发环境,包括使用Jupyter Notebook和Spyder等IDE的基本操作。通过本课程的学习,学员将能够独立搭建Numpy开发环境,并…

内存溢出的原因有哪些,如何排查线上问题?

1. java.lang.OutOfMemoryError: ......java heap space..... 堆栈溢出,代码问题的可能性极大 2. java.lang.OutOfMemoryError: GC over head limit exceeded 系统处于高频的GC状态,而且回收的效果依然 不佳的情况,就会开始报这个错误&…

Cesium 无人机视角飞行漫游,截屏

1.实现Cesium模拟无人机离屏渲染,无人机视角飞行漫游。视锥体显示 具体效果如下地址: 【CESIUM无人机视角飞行截屏】 https://www.bilibili.com/video/BV1zQ89zGE14/?share_sourcecopy_web&vd_source8239ec37df07d6a5d56c9ece00146783

vscode 打开设置

目录 方法 1(快捷键): 方法2,界面操作,有时没有 方法 1(快捷键): 按下:Cmd Shift P 输入并选择:Preferences: Open Settings (JSON) 方法2,…

繁花深处:花店建设的时代意义与多元应用—仙盟创梦IDE

花店当第一缕晨光透过花店的玻璃窗,落在带着露水的玫瑰花瓣上时,这个空间便不再只是商品交易的场所。花店作为城市肌理中充满生命力的细胞,承载着远比销售鲜花更丰富的社会意义。在快节奏的现代生活中,一束鲜花的绽放不仅是自然之…

AtomicStampedReference解决方案

1、通过引入版本戳(stamp)机制解决ABA问题: 每次修改时递增版本号执行CAS时同时检查值和版本号即使值相同但版本不同,操作也会失败2、具体代码实现 import java.util.concurrent.atomic.AtomicStampedReference;public class AtomicStampedReferenceDemo…

版本控制的详细说明介绍(已有github账号版)

说明 如果已经有一个GitHub账号,这是一个很好的起点!版本控制是一个帮助你管理代码或其他文件变化的工具,就像给你的项目加了一个“时间机器”,可以随时回溯历史、协作编辑,而不会乱套。下面我将从基础开始,层层展开说明。整个内容分为几个部分:介绍、原理、用途、操作…

基于Github Pages搭建个人博客站点:hexo环境搭建、本地预览与发布

步骤确认 Hexo 博客的源文件在哪里安装 Hexo 命令行工具:npm install -g hexo-cli在源文件目录中使用 hexo new "文章标题" 创建新文章编辑生成的 Markdown 文件使用 hexo generate 生成静态文件使用 hexo deploy 部署到这个 GitHub Pages 仓库设置Hexo博…

Shell脚本实现自动封禁恶意扫描IP

iptables 简介我们使用iptables工具实现功能iptables 是 Linux 系统上最常用的防火墙工具,可以指定策略。Shell文件创建首先我们先创建文件scanners.shvim /usr/local/bin/auto_block_ip.sh我的目标是每10分钟自动扫描,再10分钟内一个IP访问50次以上就就…

LeetCode_哈希表

哈希表(散列表)一、哈希表二、有效的字母异位词1、有效的字母异位词(力扣242)2、赎金信(力扣383)3、字母异位词分组(力扣49)4、找到字符串中所有字母异位词(力扣438)三、两个数组的交集1、两个数组的交集(力扣349)2、两个数组的交集 II(力扣350)三、其他…

2.变量和常量

1.变量2.2 变量的基本使用2.3 变量的本质 2.4 变量命名规则与规范 2.5 变量拓展-数组 1.数组的基本使用 2.常量

Java并发核心基础解析

目录 一、背景 二、Java线程模型 三、Synchronized实现原理 3.1 锁的使用 3.2 解释执行 3.3 JIT执行 3.4 锁的状态 3.5 monitorenter 3.5.1 偏向锁 3.5.2 轻量级锁 3.5.3 重量级锁 3.6 monitorexit 3.6.1 偏向锁 3.6.2 轻量级锁 3.6.3 重量级 四、可见性的真相…

线程池111

线程池框图C语言线程池详解:从基础到实现通俗理解线程池想象你开了一家快递站,每天要处理很多包裹派送:​没有线程池​:每来一个包裹就雇一个新快递员,送完就解雇问题:频繁招聘解雇成本高(线程创…

Qt-Advanced-Docking-System

直译一下 : 先进的停靠系统 github: mfreiholz/Qt-Advanced-Docking-System: Advanced Docking System for Qt 这是这个项目的起源 这个最后一次更新: githubuser0xFFFF/Qt-Advanced-Docking-System: Advanced Docking System for Qt 这是另一个人复刻…

湖南(源点咨询)市场调研 如何在行业研究中快速有效介入 中篇

我们接着起头篇来说迈克尔波特认为一个行业内存在着五种基本竞争力量,即潜在入侵者、替代产品、供方、需方以及行业内现有竞争者。如附图:即:同行业内现有竞争者的竞争能力、潜在竞争者进入的能力、替代品的替代能力、供应商的讨价还价能力、…

【无标题】消息队列(Message Queue)是一种**进程间通信(IPC)机制

消息队列(Message Queue)是一种进程间通信(IPC)机制,它允许进程通过在队列中添加和读取消息来交换数据。与管道(命名/匿名)相比,消息队列具有结构化消息、异步通信和消息持久化等特点…