vs编译生成动态库

这篇具有很好参考价值的文章主要介绍了vs编译生成动态库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

说明

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相关的头文件。需设置如下:
vs编译生成动态库
我手动创建了lib文件夹,用于存放dll和lib文件,将dll和lib文件拷贝到该路径,并进行设置。
vs编译生成动态库
设置“附加依赖项”。
vs编译生成动态库
写一个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所在路径下。这个问题待修改。

最后输出如下:
vs编译生成动态库

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

测试调用代码如下:文章来源地址https://www.toymoban.com/news/detail-432381.html

#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;
}

到了这里,关于vs编译生成动态库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vs编译生成动态库

    windows版本,vs2019 新建一c++项目,创建一个dll类型项目。 在头文件中添加一个mylib.h文件: · 在该文件之中,声明了两个需要导入到dll中的普通函数。 同时,声明和实现了一个模板函数,并将模板函数进行了实例化。 在源文件中添加一个c++文件 编译生成dll文件。注意,生成

    2024年02月02日
    浏览(33)
  • Vistual Studio 2019 编译期错误: MSB8036 找不到 Windows SDK 版本

    错误提示: 文件路径: X:Program Files (x86)Microsoft Visual Studio2019CommunityMSBuildMicrosoftVCv160Microsoft.Cpp.WindowsSDK.targets 官网 SDK 下载地址 https://developer.microsoft.com/zh-cn/windows/downloads/windows-10-sdk/

    2024年02月11日
    浏览(58)
  • 关于不同版本VS编译获得的静态库、动态库的兼容性

    看了上一篇博客还是在6月13号,一直想着写一些东西,也准备了很多内容,没想到一直拖到了现在。今天终于掀开了我的笔记本盖子,按下了开机按钮,双击浏览器图标打开了博客页(浏览器图标都差点找不到了~~),赶紧写完一篇睡觉,明晚还要给我的小可爱做饭呢。。。

    2024年02月05日
    浏览(36)
  • vs2015、vs2017、vs2019、msvc自动编译脚本

    rem 记录编译时间 echo ** 版本构建开始时间: %date% %time% build.log rem 设置编译器进程名 set DstProgram=devenv.exe rem 搜索目标进程以及其目录 echo 正在搜索\\\"%DstProgram%“, 请稍候… for %%a in (“C:Program Files (x86)”, “C:Program Files”, “D:Program Files (x86)”, “D:Program Files”) do for /f “delim

    2024年02月06日
    浏览(79)
  • VS2019远程编译arm程序

    目录 第一步、远程连接arm 第二步、选择编译器 第三步、选择好后配置JSON文件 第四步、进行Cmake远程编译 第五步、开始编译 打开vs2019 选择 【工具】--【选项】--【跨平台】连接远程arm 添加linux -GCC编译器 以上完成后就可以按照一般的方式对cmake跨平台的代码在远程arm上进行

    2024年02月08日
    浏览(47)
  • vs2019 中编译和使用 protobuf 库

    protobuf 是一种跨平台的序列化结构数据的方法,可用于网络数据传输及存储。 本文对使用 vs2019 编译 protobuf 库文件进行说明,相关代码及安装文件均来自官网下载。 ①.生成 sln 工程文件 打开 cmake ,然后选择 protobuf-v3.19.4 目录中的 cmake 文件夹 单击 configure 按钮,在打开界面

    2024年02月08日
    浏览(39)
  • VS2019编译UE4 4.27.2时出现编译报错

    完整的报错: 1.内部编译器错误。 UE4 D:UE4UnrealEngine-4.27.2-releaseEnginePluginsVirtualProductionRemoteControlSourceRemoteControlPrivateRemoteControlPreset.cpp 1870 2.严重性    代码    说明    项目    文件    行    禁止显示状态 错误    MSB3073    命令“....BuildBatchFilesRebuild.bat

    2024年02月14日
    浏览(43)
  • c#创建web项目 vs2019

    一、创建项目  二、右击项目添加新建Web服务项  三、启动测试 在刚才新建的Web服务项中简单写一个加法接口

    2023年04月08日
    浏览(44)
  • 使用VS2019开发调试Android动态库

    SDK可以安装指定的platforms和ndk-bundle。为了兼容性考虑,单独安装了版本比较老的android-ndk-r10b 安装VS2019并选择:使用C++的移动开发。 使用USB数据线连接开发手机并打开开发手机的USB调试选项。 启动VS2019,选择创建新项目 下拉框选择C++、Android,列表选择动态共享库(Android)

    2023年04月08日
    浏览(43)
  • C# WPF项目创建(基于VS 2019介绍)

    1.打开VS,选择《创建新项目》 2.选择《WPF应用》,这里设计两个有 .NET Framework框架 和 .NET core 框架, 如图所示: 区别: .NET Framework 框架只能在windows下使用 .NET core 框架支持linux 下运行 3. 项目名称根据需求自行命名,这边以“WpfApp1”来命名,位置自行选择,这边选择了\\\"E:

    2024年02月15日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包