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

查看:155
本文介绍了动态加载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与头文件不同,所以我知道我可以;像这样,但它是最好的我可以拿出来表明我试过。

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  \\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;
}

此外,您应该 export 你的函数从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中的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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