gpt4 book ai didi

c++ - 从 DLL 动态加载函数

转载 作者:IT老高 更新时间:2023-10-28 12:06:33 29 4
gpt4 key购买 nike

我正在查看 .dll 文件,我了解它们的用法,并且我正在尝试了解如何使用它们。

我创建了一个 .dll 文件,其中包含一个返回名为 funci() 的整数的函数

使用此代码,我(认为)我已将 .dll 文件导入到项目中(没有投诉):

#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 文件时,出现以下错误:

C:\Documents and Settings\User\Desktop\fgfdg\onemore.cpp||In function 'int main()':|
C:\Documents and Settings\User\Desktop\fgfdg\onemore.cpp|16|error: 'funci' was not declared in this scope|
||=== Build finished: 1 errors, 0 warnings ===|

我知道 .dll 与头文件不同,所以我知道我不能导入这样的函数,但这是我能想出的最好的方法来证明我已经尝试过了。

我的问题是,如何使用 hGetProcIDDLL 指针来访问 .dll 中的函数。

我希望这个问题是有道理的,而且我不会再找错树了。

最佳答案

LoadLibrary 并没有像你认为的那样做。它将 DLL 加载到当前进程的内存中,但它不会神奇地导入其中定义的函数!这是不可能的,因为函数调用在编译时由链接器解析,而 LoadLibrary 在运行时调用(请记住 C++ 是 statically typed 语言)。

您需要一个单独的 WinAPI 函数来获取动态加载函数的地址: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;
}

另外,你应该export正确地从 DLL 中获取函数。可以这样做:

int __declspec(dllexport) __stdcall funci() {
// ...
}

正如 Lundin 所说,free the handle to the library 是一个很好的做法。如果您不再需要它们。如果没有其他进程仍然持有同一个 DLL 的句柄,这将导致它被卸载。

关于c++ - 从 DLL 动态加载函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8696653/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com