大家好,又见面了,我是全栈君,今天给大家准备了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; }
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"); }
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/120132.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...