我正在查看 .dll 文件,我了解它们的用法并且我正在尝试了解如何使用它们.
I'm having a little look at .dll files, I understand their usage and I'm trying to understand how to use them.
我创建了一个 .dll 文件,其中包含一个函数,该函数返回一个名为 funci() 的整数
I have created a .dll file that contains a function that returns an integer named funci()
使用此代码,我(认为)已将 .dll 文件导入到项目中(没有抱怨):
using this code, I (think) I've imported the .dll file into the project(there's no complaints):
#include <windows.h>
#include <iostream>
int main() {
HINSTANCE hGetProcIDDLL = LoadLibrary("C:\Documents and Settings\User\Desktop \fgfdg\dgdg\test.dll");
if (hGetProcIDDLL == NULL) {
std::cout << "cannot locate the .dll file" << std::endl;
} else {
std::cout << "it has been called" << std::endl;
return -1;
}
int a = funci();
return a;
}
# funci function
int funci() {
return 40;
}
但是,当我尝试编译这个我认为已导入 .dll 的 .cpp 文件时,出现以下错误:
However when I try to compile this .cpp file that I think has imported the .dll I have the following error:
C:Documents and SettingsUserDesktopfgfdgonemore.cpp||In function 'int main()':|
C:Documents and SettingsUserDesktopfgfdgonemore.cpp|16|error: 'funci' was not declared in this scope|
||=== Build finished: 1 errors, 0 warnings ===|
我知道 .dll 与头文件不同,所以我知道我不能导入这样的函数,但这是我能想出的最好的方法来证明我已经尝试过了.
I know a .dll is different from a header file so I know I can't import a function like this but it's the best I could come up with to show that I've tried.
我的问题是,如何使用 hGetProcIDDLL 指针访问 .dll 中的函数.
My question is, how can I use the hGetProcIDDLL pointer to access the function within the .dll.
我希望这个问题是有道理的,而且我不会再挑错树了.
I hope this question makes sense and I'm not barking up some wrong tree yet again.
LoadLibrary 没有按照您的想法执行.它将 DLL 加载到当前进程的内存中,但它不会神奇地导入其中定义的函数!这是不可能的,因为函数调用是在编译时由链接器解析的,而 LoadLibrary 在运行时被调用(请记住,C++ 是一个 静态类型 语言).
LoadLibrary does not do what you think it does. It loads the DLL into the memory of the current process, but it does not magically import functions defined in it! This wouldn't be possible, as function calls are resolved by the linker at compile time while LoadLibrary is called at runtime (remember that C++ is a statically typed language).
您需要一个单独的 WinAPI 函数来获取动态加载函数的地址:GetProcAddress.
You need a separate WinAPI function to get the address of dynamically loaded functions: GetProcAddress.
示例
#include <windows.h>
#include <iostream>
/* Define a function pointer for our imported
* function.
* This reads as "introduce the new type f_funci as the type:
* pointer to a function returning an int and
* taking no arguments.
*
* Make sure to use matching calling convention (__cdecl, __stdcall, ...)
* with the exported function. __stdcall is the convention used by the WinAPI
*/
typedef int (__stdcall *f_funci)();
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibrary("C:\Documents and Settings\User\Desktop\test.dll");
if (!hGetProcIDDLL) {
std::cout << "could not load the dynamic library" << std::endl;
return EXIT_FAILURE;
}
// resolve function address here
f_funci funci = (f_funci)GetProcAddress(hGetProcIDDLL, "funci");
if (!funci) {
std::cout << "could not locate the function" << std::endl;
return EXIT_FAILURE;
}
std::cout << "funci() returned " << funci() << std::endl;
return EXIT_SUCCESS;
}
此外,您应该导出DLL 中的函数正确.可以这样做:
Also, you should export your function from the DLL correctly. This can be done like this:
int __declspec(dllexport) __stdcall funci() {
// ...
}
正如 Lundin 指出的那样,释放库的句柄 如果您不再需要它们.如果没有其他进程仍然持有同一个 DLL 的句柄,这将导致它被卸载.
As Lundin notes, it's good practice to free the handle to the library if you don't need them it longer. This will cause it to get unloaded if no other process still holds a handle to the same DLL.
这篇关于从 DLL 动态加载函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
当没有异常时,C++ 异常会以何种方式减慢代码速In what ways do C++ exceptions slow down code when there are no exceptions thown?(当没有异常时,C++ 异常会以何种方式减慢代码速度?)
为什么要捕获异常作为对 const 的引用?Why catch an exception as reference-to-const?(为什么要捕获异常作为对 const 的引用?)
我应该何时以及如何使用异常处理?When and how should I use exception handling?(我应该何时以及如何使用异常处理?)
C++中异常对象的范围Scope of exception object in C++(C++中异常对象的范围)
从构造函数的初始化列表中捕获异常Catching exceptions from a constructor#39;s initializer list(从构造函数的初始化列表中捕获异常)
C++03 throw() 说明符 C++11 noexcept 之间的区别Difference between C++03 throw() specifier C++11 noexcept(C++03 throw() 说明符 C++11 noexcept 之间的区别)