C#调用c++创建的动态链接库dll文件

在C#中调用外部DLL文件是一种常见的编程实践,它具有以下几个重要意义:1.代码重用;2.模块化;3.性能优化;4.安全性;5.跨平台兼容性;6.方便更新和维护;7.利用特定技术或框架;8.减少编译时间;9.保护知识产权;10.动态加载等。

调用外部DLL时,需要注意DLL的兼容性、版本控制以及依赖管理等问题,确保程序的稳定性和可靠性。

本节通过调用c++编写的dll文件显示带有噪声的正弦信号和脉冲信号。

1.1 生成动态链接库

1)打开VS2022,创建新项目

填写项目名称,选择路径,点击创建

解决方案处的结构如图所示

2)因为本人c#程序版本是32位,所以DLL也必须是32位的

3)打开pch.h文件

添加内容

#ifndef PCH_H
#define PCH_H

// 添加要在此处预编译的标头
#include "framework.h"
 
extern "C" int __declspec(dllexport) Add(int a, int b);
extern "C" __declspec(dllexport) void SinSignal(double amplitude, int T, double phase, int num, double noise, double result[]);
extern "C" __declspec(dllexport) void PulseSignal(double amplitude, int T, int start, int num, double noise, double result[]);
#endif //PCH_H

4)打开pch.cpp

添加内容

// pch.cpp: 与预编译标头对应的源文件

#include "pch.h"

// 当使用预编译的头时,需要使用此源文件,编译才能成功。
#include <cstdlib>
#include <ctime>


int Add(int a, int b)
{
    return a + b;
}

///********************* 正弦信号输出 **************//
//amplitude :幅值
// T        :一个周期个数
//phase     :相位
//num       :输出个数
//noise     :噪声幅值
//result    :结果
void SinSignal(double amplitude, int T, double phase, int num, double noise, double result[])
{
    std::srand(std::time(0));
    double pi_value = acos(-1.0); // 利用反余弦函数acos特性计算π
    for (int i = 0; i < num;i++)
    {
        double noise1 = noise * rand() / 32768;
        result[i] = amplitude * sin(phase * pi_value / 180 + pi_value * i * 2 / T) + noise1;
    }
}

///********************* 脉冲信号 **************//
//amplitude :幅值
// T        :一个周期个数
//start     :开始位置
//num       :输出个数
//noise     :噪声幅值
//result    :结果
void PulseSignal(double amplitude, int T, int start, int num, double noise, double result[])
{
    std::srand(std::time(0));
    for (int i = 0; i < num;i++)
    {
        double noise1 = noise * rand() / 32768;
        if (((i + start) / (T / 2)) % 2 == 0)
            result[i] = noise1;
        else
            result[i] = amplitude + noise1;
    }
}

5)编译

菜单栏->生成->重新生成解决方案

看输出窗口中显示生成成功

去项目文件的Debug文件夹中可以看到CppDllTest.dll文件,将其拷贝在Labview文件夹中。

1.2 调用DLL

1)新建一个项目UseCppDll_example

将CppDllTest.dll文件拷贝到UseCppDll_example\bin\x86\Debug文件夹下。

同时在VS的配置管理器中将编译平台选择成x86(因为dll文件是32位的)。

在Form1中添加一个Chart控件(chart1),一个ComboBox控件(combobox1)。

2)编写代码

导入函数部分代码

using System.Runtime.InteropServices;

[DllImport("CppDllTest.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Add(int a, int b);
[DllImport("CppDllTest.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void SinSignal(double amplitude, int T, double phase, int num, double noise, double[] result);
[DllImport("CppDllTest.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void PulseSignal(double amplitude, int T, int start, int num, double noise, double[] result);

整体程序

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.Windows.Forms;
using System.Runtime.InteropServices;
using System.Windows.Forms.DataVisualization.Charting;
namespace UseCppDll_example
{
    public partial class Form1 : Form
    {
        [DllImport("CppDllTest.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int Add(int a, int b);
        [DllImport("CppDllTest.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void SinSignal(double amplitude, int T, double phase, int num, double noise, double[] result);
        [DllImport("CppDllTest.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PulseSignal(double amplitude, int T, int start, int num, double noise, double[] result);

        public Form1()
        {
            InitializeComponent();
            Chartinit();
            comboBox1.Items.AddRange(new string[] { "正弦信号", "脉冲信号" });
            comboBox1.SelectedIndex = 0;
            comboBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10,FontStyle.Bold);

            times = 0;
            Timer timer1 = new Timer();
            timer1.Interval = 20;
            timer1.Tick += timer1_Tick;
            timer1.Start();
        }

        void Chartinit()
        {
            #region chart1
            chart1.Titles.Add("波形图");
            chart1.Titles[0].Font = new Font("Arial", 12, FontStyle.Bold);
            chart1.Series.Clear();
            //chart1.ChartAreas.Clear(); 
            //chart1.Legends.Clear();
            //chart1.BackColor = Color.Transparent;
            chart1.ChartAreas[0].BackColor = Color.Transparent;
            chart1.ChartAreas[0].Position = new ElementPosition(0, 8, 99, 90);

            //chart1.ChartAreas[0].AxisX.MajorGrid.Interval = 1;
            //chart1.ChartAreas[0].AxisY.MajorGrid.Interval = 1;
            //chart1.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.NotSet;
            chart1.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Dash;
            chart1.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Dash;
            chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.LightGray;
            chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.LightGray;
            chart1.ChartAreas[0].AxisX.LineWidth = 2;
            chart1.ChartAreas[0].AxisY.LineWidth = 2;
            chart1.Legends[0].BackColor = Color.Transparent;
            //chart1.Legends[0].Position = new ElementPosition(chart1.ChartAreas[0].Position.Width+ 1, 10, 23, 23);

            Series series = new Series();
            series.ChartType = SeriesChartType.Line; // 设置为折线图
            series.Name = "Data1";
            chart1.Series.Add(series);
            #endregion
        }

        private double times;
        void timer1_Tick(object sender, EventArgs e)
        {
            double[] result = new double[500];
            if (comboBox1.SelectedItem.ToString() == "正弦信号")
                SinSignal(2, 500, times, 500, 0.1, result);
            if (comboBox1.SelectedItem.ToString() == "脉冲信号")
                PulseSignal(2, 100, (int)times, 500, 0.1, result);
            chart1.Series["Data1"].Points.Clear();//清空点
            foreach (var value1 in result)
                chart1.Series["Data1"].Points.AddY(value1);//添加单个点
            times++;
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

重建大师重建的模型坐标有偏差怎么解决?

第一遍自由网空三&#xff0c;跑完之后刺点&#xff0c;然后控制点平差增强参数解算&#xff0c;方法如下&#xff1a; &#xff08;1&#xff09;跑完自由网空三后&#xff0c;选择编辑控制点&#xff0c;出现刺点窗口后&#xff0c;导入控制点参数 &#xff08;2&#xff09…

Apache Airflow 快速入门教程

Apache Airflow已经成为Python生态系统中管道编排的事实上的库。与类似的解决方案相反&#xff0c;由于它的简单性和可扩展性&#xff0c;它已经获得了普及。在本文中&#xff0c;我将尝试概述它的主要概念&#xff0c;并让您清楚地了解何时以及如何使用它。 Airflow应用场景 …

GEE Download Data——气温数据的下载

GEE数据下载第二弹!今天我们来分享气温数据的下载。 一、数据介绍 气温数据我们要用到的是MODIS数据产品,MOD11A2 V6.1 产品提供 1200 x 1200 公里网格内 8 天平均陆地表面温度 (LST)。 MOD11A2 中的每个像素值都是该 8 天内收集的所有相应 MOD11A1 LST 像素的简单平均值。…

分布式推理框架 xDit

1. xDiT 简介 xDiT 是一个为大规模多 GPU 集群上的 Diffusion Transformers&#xff08;DiTs&#xff09;设计的可扩展推理引擎。它提供了一套高效的并行方法和 GPU 内核加速技术&#xff0c;以满足实时推理需求。 1.1 DiT 和 LLM DiT&#xff08;Diffusion Transformers&am…

uniapp 自定义导航栏增加首页按钮,仿微信小程序操作胶囊

实现效果如图 抽成组件navbar.vue&#xff0c;放入分包 <template><view class"header-nav-box":style"{height:Props.imgShow?:statusBarHeightpx,background:Props.imgShow?:Props.bgColor||#ffffff;}"><!-- 是否使用图片背景 false…

张伟楠动手学强化学习笔记|第一讲(上)

张伟楠动手学强化学习笔记|第一讲&#xff08;上&#xff09; 人工智能的两种任务类型 预测型任务 有监督学习无监督学习 决策型任务 强化学习 序贯决策(Sequential Decision Making) 智能体序贯地做出一个个决策&#xff0c;并接续看到新的观测&#xff0c;知道最终任务结…

《只狼》运行时提示“mfc140u.dll文件缺失”是什么原因?“找不到mfc140u.dll文件”要怎么解决?教你几招轻松搞定

《只狼》运行时提示“mfc140u.dll文件缺失”的科普与解决方案 作为一名软件开发从业者&#xff0c;在游戏开发和维护过程中&#xff0c;我们经常会遇到各种运行时错误和系统报错。今天&#xff0c;我们就来探讨一下《只狼》这款游戏在运行时提示“mfc140u.dll文件缺失”的原因…

MacOS 命令行详解使用教程

本章讲述MacOs命令行详解的使用教程&#xff0c;感谢大家观看。 本人博客:如烟花般绚烂却又稍纵即逝的主页 MacOs命令行前言&#xff1a; 在 macOS 上,Terminal&#xff08;终端) 是一个功能强大的工具&#xff0c;它允许用户通过命令行直接与系统交互。本教程将详细介绍 macOS…

【计算机网络】实验6:IPV4地址的构造超网及IP数据报

实验 6&#xff1a;IPV4地址的构造超网及IP数据报 一、 实验目的 加深对IPV4地址的构造超网&#xff08;无分类编制&#xff09;的了解。 加深对IP数据包的发送和转发流程的了解。 二、 实验环境 • Cisco Packet Tracer 模拟器 三、 实验内容 1、了解IPV4地址的构造超网…

Java Web 1HTML快速入门

目录 一、Web开发介绍 1.什么是Web&#xff1f; 2.初识Web前端 二、HTML快速入门 1.什么是HTML、CSS&#xff1f; 2、案例练习 3.小结 三、VS Code开发工具 四、基础标签&样式&#xff08;HTML&#xff09; 2、实现标题--样式1&#xff08;新闻标题的颜色&#xff0…

【流程图】各元素形状和含义

判定、文档、数据、数据库、流程处理节点 矩形 - 动词 平行四边形 - 图像 下波浪 - 数据 图片来源http://baike.cu12.com/bkss/62449.shtml

利用机器学习预测离婚:从数据分析到模型构建(含方案和源码)

背景介绍 在当今社会&#xff0c;婚姻关系的稳定性受到了多方面因素的影响&#xff0c;包括经济压力、沟通问题、个人价值观差异等。离婚不仅对夫妻双方产生深远的影响&#xff0c;还可能对子女的成长环境和社会稳定造成不利影响。因此&#xff0c;理解并预测可能导致离婚的因素…

分层架构 IM 系统之 Router 架构分析

通过前面文章的分析&#xff0c;我们已经明确&#xff0c;Router 的核心职责是作为中央存储记录在线客户端的连接状态&#xff0c;Router 在本质上是一个内存数据库。 内存是一种易失性的存储&#xff0c;既如此&#xff0c;Router 的可用性如何保障呢&#xff1f; 副本是分布…

二分查找常规实现

使用二分查找有一个前提条件&#xff1a;要查找的数必须在一个有序数组里。在这个前提下&#xff0c;取中间位置数作为比较对象&#xff1a; 若要查找的值和中间数相等&#xff0c;则查找成功。 若小于中间数&#xff0c;则在中间位置的左半区继续查找。 若大于中间数&#x…

C++ 之弦上舞:string 类与多样字符串操作的优雅旋律

string 类的重要性及与 C 语言字符串对比 在 C 语言中&#xff0c;字符串是以 \0 结尾的字符集合&#xff0c;操作字符串需借助 C 标准库的 str 系列函数&#xff0c;但这些函数与字符串分离&#xff0c;不符合 OOP 思想&#xff0c;且底层空间管理易出错。而在 C 中&#xff0…

获取联通光猫的管理员密码

缘起&#xff1a;联通给免费更换了一个新的光猫&#xff0c;烽火的光路由&#xff0c;一个WAN口&#xff0c;4个LAN口&#xff0c;带USB接口&#xff0c;欣欣然接受。但是呢&#xff0c;发现以前的管理员密码CUAdmin不能用了。经过一系列查询&#xff0c;借助别人的经验&#x…

数组练习(非最终版)

作业1&#xff1a;使用二维数组输出杨辉三角 //杨辉三角 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, const char *argv[]) {int i,j,n;scanf("%d",&n);int arr[n][n];for(i0;i<n;i){arr[i][0]1;arr[…

【MySQL 进阶之路】索引概述

第06章_索引 1.什么是索引 索引是存储引擎用于快速找到数据记录的一种数据结构&#xff0c;就好比一本教科书的目录部分&#xff0c;通过目录中找到对应文章的页码&#xff0c;便可快速定位到需要的文章。MySQL中也是一样的道理&#xff0c;进行数据查找时&#xff0c;首先查…

微积分复习笔记 Calculus Volume 2 - 3.3 Trigonometric Substitution

3.3 Trigonometric Substitution - Calculus Volume 2 | OpenStax

业财一体化新篇章:外贸ERP软件重塑业务流程

业财一体化的定义&#xff08;Definition&#xff09; FMS&#xff0c;即财务管理软件&#xff08;Financial Management Software&#xff09;&#xff0c;涵盖了用于管理公司财务的多种工具和系统&#xff0c;包括预算管理、账务处理、报表生成等功能。 ERP&#xff0c;即企…