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

news2024/12/27 11:48:02

在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++;
        }
    }
}

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

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

相关文章

【Notepad++】---设置背景为护眼色(豆沙绿)最新最详细

在编程的艺术世界里&#xff0c;代码和灵感需要寻找到最佳的交融点&#xff0c;才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里&#xff0c;我们将共同追寻这种完美结合&#xff0c;为未来的世界留下属于我们的独特印记。 【Notepad】---设置背景为护眼色&#xf…

相干光学信息处理

一、光学图像相减 光学图像相减&#xff1a;一般用于检测比较两幅图像之间的差异。 实现图像相减的方法很多&#xff0c;仅介绍两种&#xff1a; (1)空域光栅编码频域解码; (2)频域光栅滤波。 1.1 空域光栅编码频域解码相减方法 分两步实现&#xff1a; 第一步&#xff1a…

鸿蒙面试题 -生命周期的执行顺序

在开始之前&#xff0c;我们先明确自定义组件和页面的关系&#xff1a; 自定义组件&#xff1a;Component装饰的UI单元&#xff0c;可以组合多个系统组件实现UI的复用&#xff0c;可以调用组件的生命周期。 页面&#xff1a;即应用的UI页面。可以由一个或者多个自定义组件组成…

【机器学习】机器学习的基本分类-监督学习-决策树-ID3 算法

ID3&#xff08;Iterative Dichotomiser 3&#xff09;是决策树的一种构造算法&#xff0c;由 Ross Quinlan 在 1986 年提出。它主要用于分类问题&#xff0c;通过信息增益选择特征来构建决策树。ID3 假设数据是离散型特征&#xff0c;且不支持连续型数据。 1. 核心思想 划分标…

Spring Boot 3.0 + MySQL 8.0 + kkFileView 实现完整文件服务

Spring Boot 3.0 MySQL 8.0 kkFileView 实现完整文件服务 背景&#xff1a;比较常见的需求&#xff0c;做成公共的服务&#xff0c;后期维护比较简单&#xff0c;可扩展多个存储介质&#xff0c;上传逻辑简单&#xff0c;上传后提供一个文件id&#xff0c;后期可直接通过此i…

泷羽sec:shell编程(9)不同脚本的互相调用和重定向操作

声明&#xff1a; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

Qt 小项目 学生管理信息系统

主要是对数据库的增删查改的操作 登录/注册界面&#xff1a; 主页面&#xff1a; 添加信息&#xff1a; 删除信息&#xff1a; 删除第一行&#xff08;支持多行删除&#xff09; 需求分析&#xff1a; 用QT实现一个学生管理信息系统&#xff0c;数据库为MySQL 要求&#xf…

IDEA的service窗口中启动类是灰色且容易消失

大家在学习Spring Cloud的过程中,随着项目的深入,会分出很多个微服务,当我们的服务数量大于等于三个的时候,IDEA会给我们的服务整理起来,类似于这样 但是当我们的微服务数量达到5个以上的时候,再启动服务的时候,服务的启动类就会变成灰色,而且还容易丢失 解决方法 我们按住…

【JMX JVM监控】Prometheus读取Trino的JMX数据到Grafana展示

trino运行拥有自己的UI来监控资源使用率&#xff0c;但领导需要更好的展示做些图表出来放到PPT里面&#xff0c;选择了用prometheus收集数据和grafana来展示图表。本文就trino的数据采集和展示做记录&#xff0c;对于prometheus和grafana的安装不做介绍。 首先要采集trino的数据…

【NIPS2024】Unique3D:从单张图像高效生成高质量的3D网格

背景&#xff08;现有方法的不足&#xff09;&#xff1a; 基于Score Distillation Sampling &#xff08;SDS&#xff09;的方法&#xff1a;从大型二维扩散模型中提取3D知识&#xff0c;生成多样化的3D结果&#xff0c;但存在每个案例长时间优化问题/不一致问题。 目前通过微…

雨晨 26100.2454 Windows 11 24H2 专业工作站 极简纯净版

文件: 雨晨 26100.2454 Windows 11 24H2 专业工作站极简 install.esd 大小: 1947043502 字节 修改时间: 2024年12月6日, 星期五, 16:38:37 MD5: 339B7FDCA0130D432A0E98957738A9DD SHA1: 2978AE0CEAF02E52EC4135200D4BDBC861E07BE8 CRC32: 8C329C89 简述&#xff1a; 由YCDIS…

IDE如何安装插件实现Go to Definition

项目背景 框架&#xff1a;Cucumber Cypress 语言&#xff1a;Javascript IDE&#xff1a;vscode 需求 项目根目录cypress-automation的cypress/integration是测试用例的存放路径&#xff0c;按照不同模块不同功能创建了很多子目录&#xff0c;cucumber测试用例.feature文…

pyqtgraph绘制实时更新数据的图

PyQtGraph是一个基于PyQt和NumPy的Python库&#xff0c;它专为实时数据可视化而设计。以绘制0~2π范围的ysin(x)为例&#xff0c;基本用法的代码如下&#xff1a; # codingutf-8import pyqtgraph as pg from pyqtgraph.Qt import QtGui, QtCore import numpy as np# pyqtgraph…

容器运行应用及Docker命令

文章目录 一、使用容器运行Nginx应用1_使用docker run命令运行Nginx应用1 观察下载容器镜像过程2 观察容器运行情况 2_访问容器中运行的Nginx服务1 确认容器IP地址2 容器网络说明3 使用curl命令访问 二、Docker命令1_Docker命令获取帮助方法2_Docker官网提供的命令说明3_docker…

小身躯大能量-供热系统通过EtherCAT转Profinet网关进行升级

在现代工业自动化领域&#xff0c;通信技术的进步对于提高系统效率、稳定性和可靠性起着至关重要的作用。EtherCAT&#xff08;Ethernet for Control Automation Technology&#xff09;作为一种实时以太网解决方案&#xff0c;因其高性能及成本效益高等特点&#xff0c;在众多…

网络编程(UDP\TCP回显服务器)

目录 套接字socket TCP和UDP特点比较 特点 比较 UDP回显服务器/客户端的编写 UDP的socket api 回显服务器 客户端 TCP回显服务器/客户端的编写 TCP的socket api 回显服务器 客户端 优化服务器 1.关闭服务器创建的socket对象 2.引入线程池&#xff0c;为多个客户…

系统监控——分布式链路追踪系统

摘要 本文深入探讨了分布式链路追踪系统的必要性与实施细节。随着软件架构的复杂化&#xff0c;传统的日志分析方法已不足以应对问题定位的需求。文章首先解释了链路追踪的基本概念&#xff0c;如Trace和Span&#xff0c;并讨论了其基本原理。接着&#xff0c;文章介绍了SkyWa…

burp常用机漏洞测试理论

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

docker学习笔记(四)--DockerFile

文章目录 一、什么是Dockerfile二、docker build命令三、dockerfile指令3.1 FROM3.2 ENV3.3 WORKDIR3.4 RUN3.5 CMD3.6 ENTRYPOINT3.7 EXPOSE3.8 ARG3.9 ADD3.10 COPY3.11 VOLUME 四、dockerfile示例 一、什么是Dockerfile Dockerfile 是用于构建 Docker 镜像的脚本文件&#…

创造未来:The Sandbox 创作者训练营如何赋能全球创造者

创作者训练营让创造者有能力打造下一代数字体验。通过促进合作和提供尖端工具&#xff0c;The Sandbox 计划确保今天的元宇宙是由一个个创造者共同打造。 2024 年 5 月&#xff0c;The Sandbox 推出了「创作者训练营」系列&#xff0c;旨在重新定义数字创作。「创作者训练营」系…