vs编译生成动态库

news2024/10/2 14:25:25

说明

windows版本,vs2019

创建一个动态库

新建一c++项目,创建一个dll类型项目。
在头文件中添加一个mylib.h文件:
·

#pragma once

#ifndef MYLIB_H
#define MYLIB_H

extern "C" __declspec(dllexport) void Hello();
extern "C" __declspec(dllexport) int Add(int a, int b);

template<typename T>
 __declspec(dllexport) T __stdcall Jiafa(T a, T b) {
    return a + b;
}

template __declspec(dllexport) int __stdcall Jiafa<int>(int a, int b);
template __declspec(dllexport) double __stdcall Jiafa<double>(double a, double b);

#endif

在该文件之中,声明了两个需要导入到dll中的普通函数。
同时,声明和实现了一个模板函数,并将模板函数进行了实例化。

在源文件中添加一个c++文件

// mylib.cpp
#include "pch.h"
#include <iostream>

// mylib.cpp
#include "pch.h"
#include <iostream>
#include "mylib.h"

using namespace std;

void Hello() {
    cout << "Hello, world!" << endl;
}

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

编译生成dll文件。注意,生成的.dll文件和.lib文件和头文件,是需要提供给其他项目工程(调用dll中的函数)的。

问题:为什么要引用pch.h文件?

预编译使用,并且需要放在引用文件的首行。

问题:extern “C” 的作用有哪些?

extern “C” 是一个 C++ 语言的特性,用于指示编译器将某段代码按照 C 语言的规则进行编译和链接。在编写动态库时,使用 extern “C” 可以确保动态库中的函数能够按照 C 语言的规则进行导出和调用,从而提高动态库的可移植性和互操作性。

extern “C” 的作用包括:

消除 C++ 名字修饰
在 C++ 中,函数名会被编译器进行修饰,以便支持函数重载等特性。这种修饰会将函数名变得很长,不方便在 C 语言中进行链接。使用 extern “C” 可以告诉编译器不要对函数名进行修饰,从而使函数名变得简短、易于理解,并且能够在 C 语言中进行链接。

例如,在 C++ 中定义一个函数:

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

编译器会将函数名修饰为 _Z3Addii,而在使用 extern “C” 修饰后,编译器会将函数名保持不变,即为 Add。

指定函数调用约定
在不同的操作系统和编译器中,函数调用的约定可能不同。使用 extern “C” 可以指定函数调用的约定为 C 语言的约定,从而保证函数能够正确地被调用。

例如,在 Windows 操作系统中,使用 __stdcall 约定传递函数参数和返回值。在使用 extern “C” __stdcall 修饰后,编译器会生成按照 __stdcall 约定进行传递参数和返回值的代码。

支持动态链接
动态链接库中的函数需要按照 C 语言的规则进行导出,以便其他程序能够正确地链接和调用这些函数。使用 extern “C” 修饰动态链接库中的函数可以确保它们按照 C 语言的规则进行导出,并且能够被其他程序正确地链接和调用。

在使用 extern “C” 修饰动态链接库时,需要注意的是,在 C++ 中,函数参数和返回值的类型和数量可能会影响函数的名字,因此需要确保函数参数和返回值的类型和数量与函数声明中的一致,否则可能导致链接错误。

问题:模板类、模板函数的导出,需要注意什么呢?

注意,需要将模板函数实例化。

使用dll

创建一个新项目,用于测试和调用dll中的函数。
我手动创建了一个include文件夹,用于存放dll相关的头文件。需设置如下:
在这里插入图片描述
我手动创建了lib文件夹,用于存放dll和lib文件,将dll和lib文件拷贝到该路径,并进行设置。
在这里插入图片描述
设置“附加依赖项”。
在这里插入图片描述
写一个cpp文件,调用dll中的函数。

// main.cpp

#include <iostream>
#include <Windows.h>
#include "mylib.h"

using namespace std;

extern __declspec(dllimport) int __stdcall Jiafa<int>(int a, int b);
extern __declspec(dllimport) int Add(int a, int b);

int main() {
    int result1 = Add(1, 2);
    cout << "result = " << result1 << endl;

    HINSTANCE hDLL = LoadLibrary(TEXT("mydll.dll"));
    if (hDLL == NULL) {
        cout << "Error: " << GetLastError() << endl;
        return 1;
    }
    typedef void (*HelloFunc)();
    HelloFunc helloFunc = (HelloFunc)GetProcAddress(hDLL, "Hello");
    if (helloFunc == NULL) {
        cout << "Error: " << GetLastError() << endl;
        return 2;
    }

    helloFunc();

    typedef int(*pAdd)(int, int);
    pAdd Add = (pAdd)GetProcAddress(hDLL, "Add");
    if (Add != NULL) {
        int result = Add(1, 2);
        cout << "result = " << result << endl;
    }

    int result = Jiafa<int>(3, 4);
    cout << "result = " << result << endl;

    FreeLibrary(hDLL);
    return 0;
}

问题:设置正确仍然无法链接到dll。

将dll拷贝到了exe所在路径下。这个问题待修改。

最后输出如下:
在这里插入图片描述

OK,所有的函数都调用到了。

模板类导出到DLL中,并测试调用

具体工程的设置,类同上文,这里不具体描述,直接给出代码。

DLL中的头文件和源文件

//头文件,tmpclss.h
#pragma once

#ifndef TMPCLSS_H
#define TMPCLSS_H

#ifdef MYTEMCLASS_EXPORTS
#define TMPCLSS_API __declspec(dllexport)
#define TMPCLSS_TEMPLATE __declspec(dllexport)
#else 
#define TMPCLSS_API __declspec(dllimport)
#define TMPCLSS_TEMPLATE __declspec(dllimport)
#endif

template <typename T>
class TMPCLSS_TEMPLATE Tmpclss
{
public:
	Tmpclss() {};
	T Add(T a, T b);
};
extern "C" template  class TMPCLSS_TEMPLATE Tmpclss<int>;
extern "C" template  class TMPCLSS_TEMPLATE Tmpclss<double>;

class TMPCLSS_API EasyClss
{
public:
	EasyClss() {};
	int Add(int a, int b);
};
#endif

源文件tmpclss.cpp

#include "pch.h"
#include "tmpclss.h"


using namespace std;

template <typename T>
T Tmpclss<T>::Add(T a, T b)
{
	return a + b;
}


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

测试调用代码如下:

#include <iostream>
#include "tmpclss.h"

using namespace std;

int main()
{
	cout << "Hello World!" << endl;
	Tmpclss<int> hisclass;
	int result = hisclass.Add(7, 8);
	cout << "result = " << result << endl;

	EasyClss easyobject;
	int result1 = easyobject.Add(7, 8);
	cout << "result1 = " << result1 << endl;	
	return 0;
}

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

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

相关文章

UG NX二次开发(C++)-建模-修改NXObject或者Feature的颜色(一)

文章目录 1、前言2、在UG NX中修改Feature的颜色操作3、采用NXOpen(C)实现3.1 创建修改特征的方法3.2 调用ModifyFeatureColor方法3.3 测试结果 1、前言 在UG NX中&#xff0c;改变NXObject和Feature的操作是不相同的&#xff0c;所以其二次开发的代码也不一样&#xff0c;我们…

优化问题的拉格朗日Lagrange对偶法原理

首先我们定义一般形式的求解x的优化问题&#xff1a; 表示优化的目标函数&#xff0c;上述为最小优化&#xff0c;实际上最大优化可以改写为的形式表示第i个不等式约束表示等式约束 1. Lagrange对偶问题 上述优化问题的拉格朗日Lagrange对偶法求解&#xff0c;是将上述带约束…

Baumer工业相机堡盟工业相机如何联合BGAPISDK和Halcon实现图像的直方图算法增强(C#)

Baumer工业相机堡盟工业相机如何联合BGAPISDK和Halcon实现图像的直方图算法增强&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机使用图像算法增加图像的技术背景Baumer工业相机通过BGAPI SDK联合Halcon使用直方图图像增强算法1.引用合适的类文件2.BGAPI SDK在图像回调…

车牌识别系统完整商用级别设计流程

简介 车牌识别&#xff08;License Plate Recognition&#xff09;是一种通过计算机视觉技术识别和提取车辆车牌上字符信息的技术。它在交通管理、智慧停车、安防监控等领域有着广泛的应用。 本项目将带完整的了解车牌识别系统设计思路&#xff0c;以及实现流程。 算法部分应…

图书管理系统【控制台+MySQL】(Java课设)

系统类型 控制台类型Mysql数据库存储数据 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址&#xff1a;https://download.csdn.net/download/qq_50954361/87737294 更多系统资源库地…

机器学习 --- 绪论

第1关&#xff1a;什么是机器学习 任务描述 ​ 本关任务&#xff1a;根据本节课所学知识完成本关所设置的选择题。 相关知识 ​ 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 什么是机器学习。 什么是机器学习 ​ 相信大家一定都非常喜欢吃西…

【Python】【进阶篇】21、Django Admin数据表可视化

目录 21、Django Admin数据表可视化1. 创建超级用户2. 将Model注册到管理后台1)在admin.py文件中声明 3. django_admin_log数据表 21、Django Admin数据表可视化 在《Django Admin后台管理系统》介绍过 Django 的后台管理系统是为了方便站点管理人员对数据表进行操作。Django …

【Java面试八股文】数据库篇

导航&#xff1a; 【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线MySQL高级篇设计模式牛客面试题 目录 请你说说MySQL索引,以及它们的好处和坏处 请你说说MySQL的索引是什么结构,为什么不用哈希表 请你说说数据库索引的底…

R语言 | 编写自己的函数

目录 一、正式编写程序 二、设计第一个函数 三、函数也是一个对象 四、程序代码的简化 五、return()函数的功能 六、省略函数的大括号 七、传递多个参数函数的应用 7.1 设计可传递2个参数的函数 7.2 函数参数的默认值 7.3 3点参数“…”的使用 八、函数也可以作为参数 …

《针灸》笔记(倪海厦先生人纪系列针灸篇)

程序员上了年纪&#xff0c;各种职业病就来了&#xff0c;人工智能成为好工具的同时&#xff0c;自己的时间也多了一些。 了解他才能判断他的真伪&#xff0c;没学过就认为中医是糟粕的&#xff0c;请划走。 学到什么记什么&#xff0c;线上线下齐下手&#xff0c;自用笔记&…

【Python基础入门学习】Python高级变量你了解多少?

认识高级变量 1. 列表 list1.1 列表的定义1.2 列表常用操作关键字、函数和方法 1.3 循环遍历1.4 列表嵌套1.5 应用场景 2. 元组 tuple2.1 元组的定义2.2 元组常用操作2.3 应用场景 3. 字典 dictionary3.1 字典的含义3.2 字典常用操作3.3 应用场景 4. 字符串 string4.1 字符串的…

基于PyQt5的图形化界面开发——模拟医院管理系统

基于PyQt5的图形化界面开发——模拟医院管理系统 0. 前言1. 需求分析2. 挂号界面的思路、UI界面代码及相应触发函数2.1 思路分析2.2 ui_guahao.py2.3 相应的触发函数代码 3. 就诊界面的思路、UI界面代码及相应触发函数3.1 思路分析3.2 ui_jiuzhen.py3.3 相关触发函数&#xff1…

如何制定专属于自己的个人目标

文章目录 前言一、自问自答二、制定目标的原则1.明确性2.衡量性3.可实现性4.相关性5.时限性 三、对目标进行计划1.5W2H1.做什么&#xff08;what to do it&#xff09;2.为什么做&#xff08;why to do it)3.何时做&#xff08;when to do it&#xff09;4.何地做&#xff08;w…

8b/10b编码方式(详细)总结附实例快速理解

目录 前言一、简介二、转换过程2.1 背景2.2 具体转换过程 三、其他相关链接1、PCI总线及发展历程总结2、PCIe物理层总结-PCIE专题知识&#xff08;一&#xff09;3、PCIe数据链路层图文总结-PCIe专题知识&#xff08;二&#xff09; 前言 本文主要通过图文方式介绍8b/10b编码&…

Hystrix线程池问题

背景&#xff1a;在一个以springcloud为基础架构的微服务项目中&#xff0c;活动期间并发量一大就会出现服务调用失败的问题。经定位发现&#xff0c;被调用服务中无对应的请求日志&#xff0c;继续通过日志查询确认是feign调用时出现服务降级&#xff0c;进入降级方法统一返回…

教会你制作自己的浏览器 —— 并将 ChatGPT 接入

前期回顾 分享24个强大的HTML属性 —— 建议每位前端工程师都应该掌握_0.活在风浪里的博客-CSDN博客2分享4个HTML5 属性&#xff0c;开发必备https://blog.csdn.net/m0_57904695/article/details/130465836?spm1001.2014.3001.5501 &#x1f44d; 本文专栏&#xff1a;开发…

对抗性攻击和防御竞争(Adversarial Attacks and Defences Competition)的通俗解读

通过我们在Pytorch对机器学习模型的安全漏洞攻击方法之Fast Gradient Sign Attack(FGSM,快速梯度符号攻击)https://blog.csdn.net/weixin_41896770/article/details/130319089 这篇文章的介绍&#xff0c;我们了解到FGSM可以对机器学习模型进行有效的攻击&#xff0c;成功的让M…

【MOMO】高水平期刊目录(持续更新)

高水平期刊目录 引言1 顶级期刊目录&#xff08;A&#xff09;1.1 IEEE Transactions on Intelligent Transportation Systems1.2 IEEE Transactions on Neural Networks and Learning Systems1.3 Engineering 2 权威期刊目录&#xff08;A&#xff09;2.1 Measurement 3 鼓励期…

从零开始三相逆变

1、题目分析 2、方案介绍 系统以220V市电作为电源&#xff0c;通过隔离调压器后分两路经过整流滤波后输入电路&#xff0c;一路为主回路供电&#xff0c;一路为辅助电源供电。三路SPWM波通过数字隔离器ISO7760送至由驱动芯片UCC27211控制三相半桥逆变电路&#xff0c;生成三路…

《嵌入式系统》知识总结2:Cortex-M3处理器和STM32

Cortex处理器分类 Cortex-A&#xff08;应用&#xff09;处理器&#xff0c;Cortex-R&#xff08;实时&#xff09;处理器&#xff0c;Cortex-M&#xff08;微控制器&#xff09;处理器...等 CM3内核优点 1. 高性能Cortex-M内核 • 采用ARM公司流行的标准内核Cortex-M3 • …