LoadLibrary("xxxx.dll") // 宏函数 依据项目定义字符格式决定函数版本
LoadLibraryA("xxxx.dll")// 窄字符版本
LoadLibraryW("xxxx.dll")// 宽字符版本
该函数返回模块句柄.
类型:HINSTANCE
本质是个结构体,里面包含一个int类型变量.
可以使用HMODULE来替换
或使用auto
例子1:
HINSTANCE MyModule{ LoadLibraryA("MyCode.dll") }; //倘若该对象内模块地址不会改变可以加const修饰
例子2:
HMODULE MyModule{ LoadLibraryA("MyCode.dll") }; //倘若该对象内模块地址不会改变可以加const修饰
例子3:
auto MyModule{ LoadLibraryA("MyCode.dll") }; //倘若该对象内模块地址不会改变可以加const修饰
GetProcAddress(模块句柄, "导出函数名")
int Add(int,int)
调用原理:
(int(*)(int,int))(导出函数地址)(参数1,参数2);
例子1:
if (const auto MyModule{ LoadLibraryA("MyCode.dll") })
{
void* IntegerAdd{ GetProcAddress(MyModule, "IntegerAdd") };
void* DoubleAdd{ GetProcAddress(MyModule,"DoubleAdd") };
std::cout << static_cast<int(*)(int, int)>(IntegerAdd)(500, 123);
std::cout << std::endl;
std::cout << static_cast<double(*)(double, double)>(DoubleAdd)(123.321, 123.321);
FreeLibrary(MyModule);
}
例子2:
if (const auto MyModule{ LoadLibraryA("MyCode.dll") })
{
std::cout << reinterpret_cast<int(*)(int, int)>(GetProcAddress(MyModule, "IntegerAdd"))(1, 2);
std::cout << std::endl;
std::cout << reinterpret_cast<double(*)(double, double)>(GetProcAddress(MyModule, "DoubleAdd"))(1., 2.);
FreeLibrary(MyModule);
}
例子3:
if (const auto MyModule{ LoadLibraryA("MyCode.dll") })
{
int(*IntegerAdd)(int, int) { reinterpret_cast<int(*)(int, int)>(GetProcAddress(MyModule, "IntegerAdd")) };
double(*DoubleAdd)(double, double) { reinterpret_cast<double(*)(double, double)>(GetProcAddress(MyModule, "DoubleAdd")) };
std::cout << IntegerAdd(1, 2);
std::cout << std::endl;
std::cout << DoubleAdd(1., 2.);
FreeLibrary(MyModule);
}
if (const auto MyModule{ LoadLibraryA("MyCode.dll") })
{
const auto IntegerAdd {reinterpret_cast<int(*)(int, int)>(GetProcAddress(MyModule, "IntegerAdd")) };
const auto DoubleAdd { reinterpret_cast<double(*)(double, double)>(GetProcAddress(MyModule, "DoubleAdd")) };
std::cout << IntegerAdd(1, 2);
std::cout << std::endl;
std::cout << IntegerAdd(55, 2);
std::cout << std::endl;
std::cout << DoubleAdd(1., 2.);
FreeLibrary(MyModule);
}
#include <iostream>
void 我是一个函数()
{
std::cout << "很抱歉以这种方式认识你" << std::endl;
}
int main()
{
void* 我是函数地址{ static_cast<void*>(&我是一个函数) };
static_cast<void(*)()>(我是函数地址)(); // 我现在等价于函数,并且被调用
return 0;
}
这是完全合法0error(s)0warning(s),在编译器(计算机)眼中很合理的代码
警告!
本文中出现使用static_cast和reinterpret_cast在对象指针和函数指针间进行转换是微软扩展语法
该语法本身未定义.
请不要在多系统兼容项目中使用,不保证任何兼容性,也不保证在非MSVC编译器中合法
为保障通用性,请使用C风格转换
1.将DLL加载到目标进程虚拟内存空间
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- yrrf.cn 版权所有 赣ICP备2024042794号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务