c++11实现DLL帮助类

用过DLL的人都会发现,在C++中调用dll中的函数有点繁琐,调用过程如下:在加载dll后还要定义一个对应的函数指针类型,接着调用GetProcAddress获取函数地址,再转成函数指针,最后调用函数

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

  用过DLL的人都会发现,在C++中调用dll中的函数有点繁琐,调用过程如下:在加载dll后还要定义一个对应的函数指针类型,接着调用GetProcAddress获取函数地址,再转成函数指针,最后调用函数。如果一个dll中有上百个函数,这中繁琐的定义会让人不胜其烦,下面将使用C++新特性中的多参数模版、function和type_traits结合起来山西爱你一个通用的dll帮助类。

1. win32 dll创建

1.1 mydll.h

#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

extern "C" MYDLL_API int Add(int, int);
extern "C" MYDLL_API float MultParmFun(int, float, char*);

1.2 mydll.cpp

#include "stdafx.h"
#include "mydll.h"

#include <iostream>
using namespace std;


MYDLL_API int Add(int a, int b)
{
    cout << "entered:" << __FUNCTION__ << endl;
    cout << "参数分别为:" << a << " "<< b << endl;
    return a + b;
}

MYDLL_API float MultParmFun(int a, float b, char* pBuff)
{
    cout << "entered:" << __FUNCTION__ << endl;
    cout << "参数分别为:" << a << " " << b << " "<< pBuff<< endl;
    if (!pBuff)
    {
        return .0;
    }

    return a * b;
}

2. dll导出函数调用一般方法

#include "stdio.h"
#include <windows.h>
#include <string>
#include <codecvt>
#include <iostream>
using namespace std;

string UncodeToAnsi(wstring &wstr)
{
    wstring_convert<codecvt<wchar_t, char, mbstate_t>> convert(new codecvt<wchar_t, char, mbstate_t>("CHS"));
    return convert.to_bytes(wstr);
}

wstring AnsiToUnicode(string &str)
{
    wstring_convert<codecvt<wchar_t, char, mbstate_t>> convert(new codecvt<wchar_t, char, mbstate_t>("CHS"));
    return convert.from_bytes(str);
}

void main()
{
    HMODULE hMode = LoadLibrary(L"mydll");
    if (!hMode)
    {
        return;
    }

    typedef int(*Add)(int, int);
    wstring wstr = L"Add";
    string str = UncodeToAnsi(wstr);
    Add AddFun = (Add)GetProcAddress(hMode, str.c_str());
    cout << AddFun(2, 3) << endl;

    typedef float(*MultParm)(int, float, char*);
    wstring wstr1 = L"MultParmFun";
    string str1 = UncodeToAnsi(wstr1);
    MultParm MultParmFun = (MultParm)GetProcAddress(hMode, str1.c_str());
    cout << MultParmFun(2, 3, "helloworld") << endl;
}

c++11实现DLL帮助类

3. DLL帮助类的实现

3.1 代码实现

#pragma once

/*
DLL函数调用帮助类

实现的关键:
    如何将一个FARPROC变成一个函数指针赋值给function,然后再调用可变参数执行,
    函数的返回值通过std::result<function<T>(ARGS...)>来泛化,使得不同的dll
    函数都可以用相同的方法来调用

需解决以下几个问题:
1.函数定义
2.函数调用多参数
3.返回值
*/

#include<functional>
#include<string>
using namespace std;

#include "mydll.h"
#include <windows.h>

bool InitDllHandle(HMODULE &hModule)
{
    hModule = LoadLibrary(L"mydll");
    if (!hModule)
    {
        return false;
    }
    return true;
}

template<typename T>
function<T> GetFunction(HMODULE &hModule, string &strFunName)
{
    FARPROC funAddress= (FARPROC)GetProcAddress(hModule, strFunName.c_str());

    return function<T>((T*)funAddress);
}

template<typename T, typename ...ARGS>
typename result_of<function<T>(ARGS...)>::type ExcecuteFunc(HMODULE &hModule, string &strFunName, ARGS ...args)
{
    function<T> fun = GetFunction<T>(hModule, strFunName);
    return fun(args...);
}

3.2 测试

#include "stdio.h"

#include "DllHelper.h"

#include <string>
#include <codecvt>
#include <iostream>
using namespace std;

string UncodeToAnsi(wstring &wstr)
{
    wstring_convert<codecvt<wchar_t, char, mbstate_t>> convert(new codecvt<wchar_t, char, mbstate_t>("CHS"));
    return convert.to_bytes(wstr);
}

wstring AnsiToUnicode(string &str)
{
    wstring_convert<codecvt<wchar_t, char, mbstate_t>> convert(new codecvt<wchar_t, char, mbstate_t>("CHS"));
    return convert.from_bytes(str);
}

void main()
{
    HMODULE hMoudle;
    bool bResult = InitDllHandle(hMoudle);
    if (!bResult)
    {
        cout << "句柄为空!" << endl;
    }
    string str = "Add";
    int a = ExcecuteFunc<int(int, int)>(hMoudle, str, 2, 3);
    string str1 = "MultParmFun";
    float b = ExcecuteFunc<float(int,float,char*)>(hMoudle, str1, 2, 3.2, (char *)"helloworld");
}

c++11实现DLL帮助类

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/120132.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号