Visual Studio 2022封装C代码为x64和x86平台动态库

1.引言

本文介绍如何使用Visual Studio 2022C语言函数封装成x64x86平台上使用的动态链接库(dll文件)并生成对应的静态链接库(lib文件),以及如何在C++程序中调用生成的dll。

程序下载:

2.示例C语言程序

假设需要开发一个动态链接库,实现复数的四则运算,定义如下头文件ComplexCal.h和源码文件ComplexCal.c。

(1)ComplexCal.h

#ifndef COMPLEXCAL_H
#define COMPLEXCAL_H
//定义复数结构体
typedef struct {double real;double imag;
} Complex;
//复数加法
Complex add(Complex a, Complex b);
//复数减法
Complex subtract(Complex a, Complex b);
//复数乘法
Complex multiply(Complex a, Complex b);
//复数除法
Complex divide(Complex a, Complex b);
#endif //COMPLEXCAL_H

(2)  ComplexCal.c

#include "CompplexCal.h"
/*** 复数加法* @param a Complex结构体* @param b Complex结构体* @return Complex结构体*/
Complex add(Complex a, Complex b) {Complex result;result.real = a.real + b.real;result.imag = a.imag + b.imag;return result;
}
/*** 复数减法* @param a  Complex结构体* @param b  Complex结构体* @return  Complex结构体*/
Complex subtract(Complex a, Complex b) {Complex result;result.real = a.real - b.real;result.imag = a.imag - b.imag;return result;
}
/*** 复数乘法* @param a  Complex结构体* @param b  Complex结构体* @return  Complex结构体*/
Complex multiply(Complex a, Complex b) {Complex result;result.real = (a.real * b.real) - (a.imag * b.imag);result.imag = (a.real * b.imag) + (a.imag * b.real);return result;
}/*** 复数除法* @param a Complex结构体* @param b Complex结构体* @return Complex结构体*/
Complex divide(Complex a, Complex b) {Complex result;double denominator = b.real * b.real + b.imag * b.imag;result.real = (a.real * b.real + a.imag * b.imag) / denominator;result.imag = (a.imag * b.real - a.real * b.imag) / denominator;return result;
}

3.创建Visual Studio 动态链接库工程并定义宏指令

3.1 创建dll工程

接下来说明如何创建Visual Studio动态链接库工程并编写相应的dll封装头文件。新建complex_cal文件夹,然后打开Visual Studio,在该目录下创建dll工程,如动图所示,然后将将示例头文件和源码文件复制到complex_cal/ComplexCal文件夹(Visual Studio解决方案文件ComplexCal.sln文件所在文件夹)内。

Visual Studio会预先创建 framework.hpch.hpch.cdllmain.cpp等4个模板文件,其中pch.h为预编译标头文件,这里用不上这些模板文件,可以将其移除或者删除。

  3.2 添加示例头文件和源码文件到解决方案内

首先需要添加ComplexCal.h(添加到头文件下)ComplexCal.c(添加到源文件下)文件到Visual Studio解决方案资源管理器内,才能让Visual Studio加载。

3.3 取消使用预编译标头

另外还需取消使用预编译标头,否则将出现C1010错误:

 取消方法在项目属性/C/C++/预编译头选项下选择不使用预编译头,如下所示:

注意在头部配置和平台上选中所有配置所有平台

3.4 在头文件中添加dll宏指令

ComplexCal.h中添加以下宏,导出函数给外部调用:

#ifndef COMPLEXCAL_H
#define COMPLEXCAL_H
//定义复数结构体
typedef struct {double real;double imag;
} Complex;//dll入口宏指令
#ifndef  COMPLEXCAL_H_API_EXPORTS
#define  COMPLEXCAL_H_API_EXPORTS __declspec(dllexport)
#endif // !COMPLEXCAL_H_API_EXPORTS//根据不同平台定义函数调用堆栈修饰宏
#ifdef _WIN64 || _M_X64//x64平台#define dll_std_call __stdcall
#elif _WIN32 || _M_IX86// x86平台
#define dll_std_call __cdecl
#endif// 一般用于将C++代码以标准C形式输出(即以C的形式被调用)
// 告诉编译器下面大括号括起来的函数是c语言函数(因为c++和c语言对函数的编译转换不一样,主要是c++中存在重载)
#ifdef __cplusplus        
extern"C" {                 
#endif
//复数加法__declspec(dllexport) Complex dll_std_call  add(Complex a, Complex b);
//复数减法__declspec(dllexport) Complex dll_std_call subtract(Complex a, Complex b);
//复数乘法__declspec(dllexport) Complex dll_std_call multiply(Complex a, Complex b);
//复数除法__declspec(dllexport) Complex dll_std_call divide(Complex a, Complex b);
#ifdef __cplusplus
}
#endif
#endif //COMPLEXCAL_H

3.5  选择目标平台并生成解决方案来生成dll

在Visual Studio工具栏上选择dll的构建配置和目标平台,例如Debug和x64。在Visual Studio中,Debug和Release是两种不同的构建配置。它们之间的主要区别在于编译器如何优化代码并生成可执行文件。

在Debug模式下,编译器会生成包含调试符号的二进制文件。这些符号可以用于在代码中设置断点、跟踪变量值等操作,以便进行调试。此外,编译器通常会关闭优化,以便使得调试更容易。

在Release模式下,编译器通常会启用各种优化,以生成更快、更紧凑的代码。这些优化可能会包括删除未使用的代码、内联函数、循环展开和其他技术。此外,由于没有调试符号,生成的文件大小也比Debug模式下的要小得多。

 然后运行工具栏生成/生成解决方案来生成dll。

对于x64平台,生成的dll文件位于解决方案(.sln文件)同目录的x64文件夹下,对于Debug构建配置,位于x64/DebugRelease构建配置位于x64/Release。对于x86平台的Debug构建配置,则位于解决方案文件同目录的Debug文件夹,x86平台的Release构建配置则位于解决方案文件同目录的Release文件夹。

 打开上述目录,其中的ComplexCal.dllComplexCal.lib即我们需要的dll文件,其它文件为编译和链接所需的中间文件。

4.在C++程序中引用动态库

4.1 演示工程配置

创建C++控制台应用,测试生成的复数运算dll。首先使用Visual Studio创建一个控制台应用工程,命名为ComplexCalApplication

将上述生成的dlllib文件以及ComplexCal.h头文件复制到解决方案文件ComplexCalApplication.sln所在目录的include文件夹下,这里以X64_Release为例。

然后添加ComplexCal.h头文件到解决方案资源管理器的头文件下,让Visual Studio能发现该文件。还需在项目属性->C/C++->常规选项下添加include文件夹为附加包含夹,以让链接器能发现并链接dlllib文件:

另外定义生成后事件,让Visual Studio自动复制dll文件到可执行文件所在目录,避免出现dll丢失错误。生成后事件指令如下:

xcopy /y "$(ProjectDir)\include\*.dll" "$(TargetDir)"

上述命令表示在生成结束后自动将 include文件夹下的dll文件复制到可执行文件所在目录内。在项目属性中定义生成后事件的方法如下:

4.2 dll调用

在C++程序中调用dll以下几个步骤:

  1. 将 DLL 的头文件包含到应用程序中。
  2. 定义生成后事件将dll文件复制到可执行文件所在文件夹下。

如代码所示:

#include <iostream>
//引入dll头文件
#include "include/ComplexCal.h"
int main()
{Complex a, b, sum, difference;std::cout << "Enter the real and imaginary parts of the first complex number: ";std::cin >> a.real >> a.imag;std::cout << "Enter the real and imaginary parts of the second complex number: ";std::cin >> b.real >> b.imag;sum = add(a, b);difference = subtract(a, b);std::cout << "Sum: " << sum.real << " + " << sum.imag << "i" << std::endl;std::cout << "Difference: " << difference.real << " + " << difference.imag << "i" << std::endl;return 0;}

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

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

相关文章

CleanMyMac X2024(Mac优化清理工具)v4.14.5中文版

CleanMyMac X是一款颇受欢迎的专业清理软件&#xff0c;拥有十多项强大的功能&#xff0c;可以进行系统清理、清空废纸篓、清除大旧型文件、程序卸载、除恶意软件、系统维护等等&#xff0c;并且这款清理软件操作简易&#xff0c;非常好上手&#xff0c;特别适用于那些刚入手苹…

提升英语学习效率,尽在Eudic欧路词典 for Mac

Eudic欧路词典 for Mac是一款专为英语学习者打造的强大工具。无论您是初学者还是高级学习者&#xff0c;这款词典都能满足您的需求。 首先&#xff0c;Eudic欧路词典 for Mac具备丰富的词库&#xff0c;涵盖了各个领域的单词和释义。您可以轻松查询并学习单词的意思、用法和例…

数据泄露警报:不同行业危机解析与迅软DSE的拯救之道

在如今全球信息数字化不断加速的时代里&#xff0c;数据资料的价值更为突出&#xff0c;根据IBM数据显示&#xff0c;数据泄露的平均成本接近440万美元。一旦泄露可能意味着丢失信息、声誉受损&#xff0c;并可能导致延误和生产力损失。那么不同行业一旦发生了数据泄露将会面临…

大 O 表示法在机器学习中的重要性

一、介绍 在不断发展的机器学习领域&#xff0c;算法的效率至关重要。大 O 表示法成为这方面的一个关键工具&#xff0c;它提供了一种描述算法性能或复杂性的语言&#xff0c;特别是在时间和空间方面。本文探讨了 Big O 表示法在机器学习中的重要性&#xff0c;阐明了它在算法选…

狗dog目标检测数据集VOC+YOLO格式1W+张

狗&#xff0c;是食肉目犬科 [11]犬属 [13]哺乳动物 [12]&#xff0c;别称犬&#xff0c;与马、牛、羊、猪、鸡并称“六畜” [13]。狗的体型大小、毛色因品种不同而不同&#xff0c;体格匀称&#xff1b;鼻吻部较长&#xff1b;眼呈卵圆形&#xff1b;两耳或竖或垂&#xff1b;…

一文搞懂OSI参考模型与TCP/IP

OSI参考模型与TCP/IP 1. OSI参考模型1.1 概念1.2 数据传输过程 2. TCP/IP2.1 概念2.2 数据传输过程 3. 对应关系4. 例子4.1 发送数据包4.2 传输数据包4.3 接收数据包 1. OSI参考模型 1.1 概念 OSI模型&#xff08;Open System Interconnection Reference Model&#xff09;&a…

复制粘贴——QT实现原理

复制粘贴——QT实现原理 QT 剪贴板相关类 QClipboard 对外通用的剪贴板类&#xff0c;一般通过QGuiApplication::clipboard() 来获取对应的剪贴板实例。 // qtbase/src/gui/kernel/qclipboard.h class Q_GUI_EXPORT QClipboard : public QObject {Q_OBJECT private:explici…

安装鸿蒙开发者工具DevEco Studio

1.进入官网下载工具 https://developer.harmonyos.com/cn/develop/deveco-studio/ 选择您电脑对应的系统下载即可 2.安装 很简单直接点击“next”,此处不做赘述 3.配置环境 安装完成后&#xff0c;打开DevEco Studio 会提示配置环境。安装node.js和ohpm 如果不小心关了&a…

【第1期】SpringSecurity基于角色和权限的细粒度接口权限控制

SpringSecurity 细粒度权限控制 一、Role 和 Authority的区别 角色用来表示某一类权限的集合&#xff0c;权限粒度更小&#xff0c;方便细粒度控制 二、创建用户、角色、权限相关表&#xff1a; CREATE TABLE common_user (id bigint(20) NOT NULL COMMENT 主键id,login_na…

Spring Boot 3 整合 Mybatis-Plus 动态数据源实现多数据源切换

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

C#学习笔记 - C#基础知识 - C#从入门到放弃

C# 持续更新中~~ 上次更新日期&#xff1a;20231215 第1节 C# 简单介绍1.1 C# 是什么1.2 C# 强大的编程功能1.3 C# 发展史1.4 C#与Java区别 第2节 C#基本语法2.1 C#程序结构2.2 C# 结构解析2.3 命名空间及标识符、关键字2.3.1 别名的使用2.3.2 标识符2.3.3 C#关键字 第3节 变量…

jmeter,动态参数之随机数、随机日期

通过函数助手&#xff0c;执行以下配置&#xff1a; 执行后的结果树&#xff1a; 数据库中也成功添加了数据&#xff0c;对应字段是随机值&#xff1a;

gitbash下载安装

参考教程 零、下载 官网地址 2.43.0win64 链接&#xff1a;https://pan.baidu.com/s/16urs_nmky7j20-qNzUTTkg 提取码&#xff1a;7jaq 一、安装 图标组件&#xff08;Additional icons&#xff09;&#xff1a;选择是否创建桌面快捷方式&#xff1b;桌面浏览&#xff08;Win…

国标级联/流媒体音视频平台EasyCVR设备录像下载异常该如何解决?

视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#xff0c;也能支…

视频推拉流平台EasyDSS点播文件播放请求添加token验证的实现方法

EasyDSS视频直播点播平台可提供一站式的视频推拉流、转码、点播、直播、播放H.265编码视频等服务&#xff0c;搭配RTMP高清摄像头使用&#xff0c;可将设备的实时流推送到平台上&#xff0c;实现无人机视频推流直播等应用。今天我们来介绍下EasyDSS系统点播文件播放请求添加tok…

MQTT 介绍与学习 —— 筑梦之路

之前写过的相关文章&#xff1a; MQTT协议&#xff08;转载&#xff09;——筑梦之路_mqtt url-CSDN博客 k8s 部署mqtt —— 筑梦之路-CSDN博客 CentOS 7 搭建mqtt服务——筑梦之路_腾讯云宝塔搭 centos 7.9.2009 x86_64 建标准mqtt服务器-CSDN博客 mqtt简介 MQTT&#xff…

轻量封装WebGPU渲染系统示例<50>- Json数据描述材质等场景信息

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/DataDrivenScene2.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如下: json场景数据: {"renderer": {"mtplE…

Java网络编程,使用UDP实现TCP(三), 基本实现四次挥手

简介 四次挥手示意图 在四次挥手过程中&#xff0c;第一次挥手中的Seq为本次挥手的ISN&#xff0c; ACK为 上一次挥手的 Seq1&#xff0c;即最后一次数据传输的Seq1。挥手信息由客户端首先发起。 实现步骤&#xff1a; 下面是TCP四次挥手的步骤&#xff1a; 第一次挥手&…

LV.13 D4 uboot使用 学习笔记

一、uboot环境变量命令 1.1 uboot模式 自启动模式 uboot 启动后若没有用户介入&#xff0c;倒计时结束后会自动执行自启动环境变量 (bootcmd) 中设置的命令&#xff08;一般作加载和启动内核&#xff09; 交互模式 倒计时结束之前按下任意按键 uboot 会进…

异地现场工控设备,如何实现远程配置、调试?

南京某企业专注于工业物联领域&#xff0c;在相关项目中往往会在各个点位部署基于Linux系统的中控主机&#xff0c;实现各类物联设备信息的采集、汇总。但是&#xff0c;由于各点位分散多地&#xff0c;且数量达到了上百个&#xff0c;虽然中控主机具备4G物联网接入能力&#x…