从DLL动态加载函数 [英] Dynamically load a function from a DLL

查看:129
本文介绍了从DLL动态加载函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在看一下.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;
}

但是,当我尝试编译我认为导入的.cpp文件.dll我有以下错误:

However when I try to compile this .cpp file that I think has imported the .dll I have the following error:

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与头文件不同,所以我知道我可以; t导入一个函数像这样,但是我可以想出来,我已经尝试过了。

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加载到当前进程的内存中,但它不会在中导入在其中定义的函数!这是不可能的,因为函数调用在编译时由链接器解析,而$ code> 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  \\fgfdg\\dgdg\\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;
}

另外,你应该导出。这可以这样做:

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动态加载函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆