0


[速成] Visual Studio C/C++创建Dll(动态链接库)并调用

以下示例均在VS2022环境下完成。

一、创建动态链接库(C++)

1.新建动态链接库项目模版:

2.新建项目MyC++_Dll后,默认目录结构如下:

3.添加并新建头文件MyC++_Dll.h和源码文件MyC++_Dll.cpp(用于声明和定义函数接口):

4.MyC++_Dll.h示例如下:

#pragma once

#ifdef _EXPORTING
#define _DLL_API _declspec(dllexport)
#else
#define _DLL_API _declspec(dllimport)
#endif

#ifdef __cplusplus
class Dll_Class
{
public:
    Dll_Class();
    ~Dll_Class();
    virtual int Addition(int a, int b);
};

extern "C"
{
    _DLL_API Dll_Class *CreateObject();
    _DLL_API void ReleaseObject(Dll_Class *pObject);
    _DLL_API int Multiplication_TypeC(int a, int b);
    _DLL_API int Addition_TypeC(int a, int b);
}
#endif

注意:

_EXPORTING 是笔者自定义宏,用于区分当前是导出dll还是调用dll,要实现导出函数,还需要在实现Dll函数功能的项目属性里,添加预处理定义(记得结尾加分号),如下图:

_declspec(dllexport) 是VC的关键字,表示导出函数到dll;

_declspec(dllimport) 是VC的关键字,表示从dll调用函数;

_DLL_API 是笔者自定义宏,用于给需要导入导出的函数接口简化代码、快速替换_declspec(dllimport)和_declspec(dllexport)关键字;

如果_EXPORTING被定义,采用导出模式,否则为调用模式;

__cplusplus 宏表示采用的是C++的编译环境,通过#ifdef __cplusplus可判断当前是否为C++的编译环境;

extern "C" {} 表示代码块内的函数采用C语言方式编译.

5.MyC++_Dll.cpp示例如下(具体功能实现):

#include "pch.h"
#include "MyC++_Dll.h"

Dll_Class::Dll_Class() {

}

Dll_Class::~Dll_Class() {

}

int Dll_Class::Addition(int a, int b) {
    return a + b;
}

Dll_Class* CreateObject() {
    Dll_Class* pClass = new Dll_Class();
    return pClass;
}

void ReleaseObject(Dll_Class* pObject) {
    if (pObject) {
        delete pObject;
        pObject = NULL;
    }
}

int Multiplication_TypeC(int a, int b) {
    return a * b;
}

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

6.编译代码生成lib和dll等文件,如下图:

二、创建动态链接库(C)

1.新建空项目MyC_Dll:

2.添加并新建头文件MyC_Dll.h和源码文件MyC_Dll.cpp(用于声明和定义函数接口):

3.MyC_Dll.h示例如下:

#ifndef _MYC_DLL_HEADER_FILE
#define _MYC_DLL_HEADER_FILE

#ifdef   _EXPORTING
#define  _DLL_API __declspec(dllexport)
#else
#define  _DLL_API __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C"
{
    _DLL_API int Addition_TypeC(int a, int b);
    _DLL_API int Multiplication_TypeC(int a, int b);
}
#endif
#endif

注意:

_EXPORTING 是笔者自定义宏,用于区分当前是导出dll还是调用dll,要实现导出函数,还需要在实现Dll函数功能的项目属性里,添加预处理定义(记得结尾加分号),如下图:

_declspec(dllexport) 是VC的关键字,表示导出函数到dll;

_declspec(dllimport) 是VC的关键字,表示从dll调用函数;

_DLL_API 是笔者自定义宏,用于给需要导入导出的函数接口简化代码、快速替换_declspec(dllimport)和_declspec(dllexport)关键字;

如果_EXPORTING被定义,采用导出模式,否则为调用模式;

__cplusplus 宏表示采用的是C++的编译环境,通过#ifdef __cplusplus可判断当前是否为C++的编译环境;

extern "C" {} 表示代码块内的函数采用C语言方式编译.

4.MyC_Dll.cpp示例如下(具体功能实现):

#include "MyC_Dll.h"

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

int Multiplication_TypeC(int a, int b) {
    return a * b;
}

5.要在项目属性里修改配置类型为动态库(.dll)才能生成dll,如下图:

6.编译代码生成lib和dll等文件,如下图:

三、隐式调用Dll

1.创建空项目Call_dll:

2.添加并新建源码文件Call_Dll.cpp:

3.Call_Dll.cpp示例如下(具体调用函数接口实现):

//定义是否用C语言编译
//#define USING_C

#ifdef USING_C
#include <stdio.h>

#include "../MyC_Dll/MyC_Dll.h"
#pragma comment(lib, "../Debug/MyC_Dll.lib")
#else
#include <iostream>
using namespace std;

#include "../MyC++_Dll/MyC++_Dll.h"
#pragma comment(lib, "../Debug/MyC++_Dll.lib")
#endif

int main()
{
#ifdef USING_C
    int a = 8, b = 6;

    printf("Addition_TypeC result = %d\n", Addition_TypeC(a, b));
    printf("Multiplication_TypeC result = %d\n", Multiplication_TypeC(a, b));
#else
    int a = 8, b = 6;
    Dll_Class* pMyDll_Object = CreateObject();

    cout << "My_Dll_Class.Addition result = " << pMyDll_Object->Addition(a, b) << endl;
    cout << "Addition_TypeC result = " << Addition_TypeC(a, b) << endl;
    cout << "Multiplication_TypeC result = " << Multiplication_TypeC(a, b) << endl;

    ReleaseObject(pMyDll_Object);
#endif

    return 0;
}

注意:

(1)#pragma comment(lib, Lib文件)和 #include "dll头文件"要确保真实存在的路径.

(2)笔者这里用#ifdef USING_C来选择用C语言还是C++风格(二者主要区别在于用C还是C++编程语句,以及调用Dll的数据结构类型,是否是C++独有的)调用.

4.Dll文件复制到Call_Dll项目生成的目标路径,如下图:

注意:隐式调用,要求dll文件与exe文件在同一目录或者dll文件注册在操作系统的全局运行环境.

5.编译代码生成exe文件,运行结果如下图:

C++:

C:

四、显式调用Dll

1.创建空项目Call_dll:

2.添加并新建源码文件Call_Dll.cpp:

3.Call_Dll.cpp示例如下(具体调用函数接口实现):

//定义是否用C语言编译
//#define USING_C

#ifdef USING_C
#include <stdio.h>
#else
#include <iostream>
using namespace std;
#endif
#include <Windows.h>

int main()
{
    HINSTANCE hdll;

#ifdef USING_C
    typedef int (*_Fun_Addition_TypeC)(int, int);
    typedef int (*_Fun_Multiplication_TypeC)(int, int);

    hdll = LoadLibrary(L"MyC_Dll.dll");
    if (hdll == NULL) {
        printf("Error: Load dll fail.\n");
        return -1;
    }

    _Fun_Addition_TypeC Addition_TypeC;
    _Fun_Multiplication_TypeC Multiplication_TypeC;

    Addition_TypeC = (_Fun_Addition_TypeC)GetProcAddress(hdll, "Addition_TypeC");
    Multiplication_TypeC = (_Fun_Multiplication_TypeC)GetProcAddress(hdll, "Multiplication_TypeC");

    if (Addition_TypeC == NULL || Multiplication_TypeC == NULL) {
        printf("Error: Call functions fail.\n");
        return -2;
    }

    int a = 8, b = 6;
    printf("Addition_TypeC result = %d\n", Addition_TypeC(a, b));
    printf("Multiplication_TypeC result = %d\n", Multiplication_TypeC(a, b));
#else
    class _Dll_Class
    {
    public:
        //_Dll_Class();
        //~_Dll_Class();
        virtual int Addition(int a, int b)=0;
    };

    typedef _Dll_Class* (*_Fun_CreateObject)();
    typedef void (*_Fun_ReleaseObject)(_Dll_Class*);
    typedef int (*_Fun_Multiplication_TypeC)(int, int);
    typedef int (*_Fun_Addition_TypeC)(int, int);

    hdll = LoadLibrary(L"MyC++_Dll.dll");
    if (hdll == NULL) {
        printf("Error: Load dll fail.\n");
        return -1;
    }

    _Fun_CreateObject CreateObject = (_Fun_CreateObject)GetProcAddress(hdll, "CreateObject");
    _Fun_ReleaseObject ReleaseObject = (_Fun_ReleaseObject)GetProcAddress(hdll, "ReleaseObject");
    _Fun_Addition_TypeC Addition_TypeC = (_Fun_Addition_TypeC)GetProcAddress(hdll, "Addition_TypeC");
    _Fun_Multiplication_TypeC Multiplication_TypeC = (_Fun_Multiplication_TypeC)GetProcAddress(hdll, "Multiplication_TypeC");

    if (CreateObject == NULL || ReleaseObject ==NULL || Addition_TypeC == NULL || Multiplication_TypeC == NULL) {
        printf("Error: Call functions fail.\n");
        return -2;
    }

    int a = 8, b = 6;
    _Dll_Class* pMyDll_Object = CreateObject();

    cout << "My_Dll_Class.Addition result = " << pMyDll_Object->Addition(a, b) << endl;
    cout << "Addition_TypeC result = " << Addition_TypeC(a, b) << endl;
    cout << "Multiplication_TypeC result = " << Multiplication_TypeC(a, b) << endl;

    ReleaseObject(pMyDll_Object);
#endif

    if (hdll == NULL) {
        FreeLibrary(hdll);
        hdll = NULL;
    }

    return 0;
}

注意:

(1)LoadLibrary(dll文件路径)要确保真实存在的路径.

(2)笔者这里用#ifdef USING_C来选择用C语言还是C++风格(二者主要区别在于用C还是C++编程语句,以及调用Dll的数据结构类型,是否是C++独有的)调用.

4.Dll文件复制到LoadLibrary(dll文件路径)指定的路径,如下图:

注意:显式调用,要求dll文件路径与LoadLibrary(dll文件路径)相同,当前示例与exe文件同目录。

5.编译代码生成exe文件,运行结果如下图:

C++:

C:

标签: c++ c语言

本文转载自: https://blog.csdn.net/software_metagalaxy/article/details/134164795
版权归原作者 Felix Peng 所有, 如有侵权,请联系我们删除。

“[速成] Visual Studio C/C++创建Dll(动态链接库)并调用”的评论:

还没有评论