首页 > 编程语言 >C++创建与调用dll动态链接库

C++创建与调用dll动态链接库

时间:2024-09-12 22:15:39浏览次数:10  
标签:调用 int C++ dll 动态链接库 include DllClass

C++创建与调用dll动态链接库(MinGW64 Dev-C++)

本文使用的是dev-c++,如果涉及到VC++中不一样的操作,也会适当进行区分。

项目一:创建DLL

1、创建一个DLL类型的项目,当前命名为dlltest,并选择合适的路径进行保存。

 2、在生成的预设置代码中,加入如下代码

复制代码
//这是头文件dll.h
#ifndef _DLL_H_
#define _DLL_H_

#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif

class DLLIMPORT DllClass
{
    public:
        DllClass();
        virtual ~DllClass();
        void HelloWorld(char* info);
};

extern "C" 
{
    DLLIMPORT int HW(int n);
}

DLLIMPORT int func(int n);


#endif
复制代码 复制代码
/*这是主体文件dllmain.cpp */
#include "dll.h"
#include <windows.h>

DllClass::DllClass()
{

}

DllClass::~DllClass()
{

}

void DllClass::HelloWorld(char* info)
{
    MessageBox(0, info,"Hi",MB_ICONINFORMATION);
}

DLLIMPORT int HW(int n)
{
    return n;
}

DLLIMPORT int func(int n)
{
    return n;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            break;
        }
        case DLL_PROCESS_DETACH:
        {
            break;
        }
        case DLL_THREAD_ATTACH:
        {
            break;
        }
        case DLL_THREAD_DETACH:
        {
            break;
        }
    }
    
    /* Return TRUE on success, FALSE on failure */
    return TRUE;
}
复制代码

在上面的代码中,我们加入了HW和func两个导出函数,以及一个DllClass(自动生成)导出类。

点击编译后,我们可以在项目文件夹中,看到dlltest.dll,这就是我们需要的目标动态链接库。libdlltest.a则是vc里需要用到的lib文件。

3、extern "C"说明

当前可以用记事本打到libdlltest.def文件,可以看到如下内容:

加了extern "C"的HW函数地址偏移量还是HW,没有加extern "C"的func函数,地址偏移量变成了_Z4funci。这个地址在动态调用导出函数的过程中会用到。

 

项目二:动态调用dll导出的函数

1、再创建一个C++项目,将项目一生成的dll文件放入项目文件夹中:

 2、使用LoadLibrary和和GetProcAddress动态载入动态链接库,并调用导出的函数:

复制代码
#include <iostream>
#include <windows.h>
using namespace std;

int main()
{
    HMODULE hMod=LoadLibrary("dlltest.dll");
    if(hMod==NULL)
    {
        cerr<<"load lib error";
        return 1;
    }
    
    Func f=(Func)GetProcAddress(hMod,"HW");
    cout<<f(200);
    
    FreeLibrary(hMod);
    
    return 0;
}
复制代码

在GetProcAddress中,调用HW函数可以直接传入偏移量HW;

如果调用func函数,则要传入偏移量“_Z4funci”;因为func函数没有声明为extern "C"。

3、特别备注,当前这种方式无法使用LoadLibrary和GetProcAddress获取导出类。

因为GetProcAddress获取的是函数的地址偏移量,为了可以动态使用导出的类,必须使用将一个纯虚函数做为基类,将导出创建和销毁类的函数。具体做法如下:

复制代码
//dll.h
#include <stdlib.h>
#include <stdio.h>

class virtualXXX
{
public:
    virtual void functionOne() = 0;
    virtual void functionTwo() = 0;
};


#if defined(_WINDOWS)
    #ifdef XXX_API
        #define  XXX_API  __declspec(dllexport)
    #else
        #define  XXX_API  __declspec(dllimport)
    #endif
#else
    #define  XXX_API
#endif

class XXX_API xxx : public virtualXXX
{
public:
    void functionOne()
    {
        printf ( "One\n" );
    }

    void functionTwo()
    {
        printf ( "Two\n" );
    }
};

extern "C" XXX_API virtualXXX * create();
extern "C" XXX_API void  delete_object( virtualXXX  * p );
 

//dll.cpp
virtualXXX * create()
{
    return ( new xxx() );
}

void  delete_object( virtualXXX  * p )
{
    if ( p )
    {
        delete p;
        p = NULL;
    }
}
复制代码

动态调用:

复制代码
#include <Windows.h>
typedef virtualXXX *(fun_create)(void);
fun_create*            vc_create = NULL;

int main()
{
    HINSTANCE dllHandle = NULL;
    dllHandle = LoadLibrary( "Win32_Test_dll.dll" );
    vc_create = ( fun_create* )GetProcAddress( dllHandle,"create" );
    virtualXXX * xxxHandle = vc_create();


    xxxHandle->functionOne();
    xxxHandle->functionTwo();
  
    delete_object(xxxHandle);
}
复制代码

这个方法参考文章C++动态库导出类,及使用,博主未实际进行测试。

 

项目三:静态调用导出的类

静态调用dll,在VC++需要头文件、dll和对应的lib文件(即项目一中生成的 libdlltest.a)。然后再使用#pragma comment(lib,"lib文件路径")对编译器进行配置lib路径,之后再进行调用。详细过程可以参考《c++生成DLL并调用》

本文着重调论Dev-C++下的静态调用。对于MinGW64静态调用dll,只需要dll文件和相关的头文件,项目结构如下:

其中main.cpp中调用类的代码如下:

复制代码
#include <iostream>
#include <windows.h>
#include "dll.h" 
using namespace std;

int main()
{
    DllClass c;
    char str[]="hello";
    c.HelloWorld(str);
    
    return 0;
}
复制代码

可以看到,无需在代码中进行任何设置。因为只有在链接的过程c++才会去找DllClass这个类的真实地址。

在编译成exe时,有如下两种方法:

方法一、可以使用命令行进行编译:

通过cmd进入main.cpp所在文件夹路径,运行:g++ -o main.exe main.cpp -I . -L . -ldlltest

即可编译生成可执行文件exe。编译参数说明如下:

-I搜索头文件的目录
-I .在当前文件夹下搜索头文件
-L搜索动态库的目录
-L .在当前文件夹下搜索动态库

方法二、将参数加入编译选项中:

如果觉得用命令行编译太麻烦,可以将-I -L和-l加入Dev-C++的编译器选项中。

这样点击“编译运行”就可以正确找到对应的dll进行编译链接,正确生成exe文件。

 

本文关于Dev-C++创建并调用动态链接库dll到这里就结束了,欢迎大家指正:)

标签:调用,int,C++,dll,动态链接库,include,DllClass
From: https://www.cnblogs.com/Leo_wl/p/18411204

相关文章

  • C/C++ 学生管理系统的文件读取与写入
    代码中文件读取函数read_file()存在一些问题,望指出.`#includeincludedefineSIZE100usingnamespacestd;staticintnums_stu=0;typedefstructStudent{char*name;char*ID; //占10个字符doublescore_one;doublescore_two;doublescore_three;doubletota......
  • C++中的基本运算符----逻辑运算符(&&、||、!)的实例讲解
    在C++中,逻辑运算符用于处理布尔值(true和false),并用于复合条件的判断。主要的逻辑运算符包括:目录1.逻辑与运算符(&&):2.逻辑或运算符(||):3.逻辑非运算符(!):1.逻辑与运算符(&&):当且仅当两个操作数都为true时,结果才为true。示例:if(a>0&&b>0)下面......
  • C++插件管理系统
    插件加载目录结构execute   plug.exe   plugify.dll   plugify.pconfig   res      cpp-lang-module.pmodule      example_plugin.pplugin      bin         cpp-lang-module.dll         exampl......
  • C++---string类常见接口
    介绍 string类详情===>>>https://cplusplus.com/reference/string/string/?kw=string1.string是表示字符串的字符串类(感觉就像一个动态的字符数组)2.该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。3.string在底层实际是:basic_string模......
  • C++入门基础知识64——【关于 C+++数据抽象】
    成长路上不孤单......
  • C++音视频毕设项目计划书
    最近我经常收到私信,询问如何准备秋季招聘,以及学生阶段如何参与实习或进行小项目来提升自己的技能。我个人建议,找到相关行业的公司进行实习是个不错的选择。不过,自己也可以尝试做一些小项目,不断改进和优化,以提升动手能力。以下是一个音视频项目计划书,分享给大家:项目开发计划书:流媒......
  • C++读取命令行参数的学习(BOOST库)
    在c++工程中,经常需要通过命令行参数来获取程序运行所需要的信息。作者在实际工作中学习了Boost库,这里根据作者的理解,写了一个依托boost库完成命令行参数提取的程序模版,请大佬批评!!#defineOK0#defineExit-99//主程序#include<iostream>#include"XApp.h"intmain(int......
  • 题解 力扣 LeetCode 105 从前序与中序遍历序列构造二叉树 C/C++
    题目传送门:105.从前序与中序遍历序列构造二叉树-力扣(LeetCode)https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/每次在中序遍历序列片段中找到前序遍历序列队首,这是该层的根节点该位置左侧是左子树,右侧是右子树再......
  • apppluginbase.dll丢失怎么修复?高效修复方案:如何找回并注册apppluginbase.dll文件
    当您在运行某些应用程序或游戏时遇到“apppluginbase.dll丢失”或“找不到apppluginbase.dll”等错误提示时,这通常意味着您的系统中缺少或损坏了这个重要的动态链接库文件。apppluginbase.dll是许多基于特定框架或平台的应用程序所依赖的关键组件之一,缺失该文件会导致程序无法......
  • 《黑神话:悟空》游戏启动时闪退弹窗“找不到msvcp100.dll”文件该怎么办?黑神话悟空游戏
    在启动《黑神话:悟空》时,若遇到闪退弹窗并提示“找不到msvcp100.dll”文件,别紧张。这可能是文件缺失造成的。您可以使用系统的修复工具尝试解决,或者从可靠来源获取该文件进行安装,有望解决此问题。本篇将为大家带来《黑神话:悟空》游戏启动时闪退弹窗“找不到msvcp100.dll”文件该......