为了账号安全,请及时绑定邮箱和手机立即绑定

从DLL动态加载函数

从DLL动态加载函数

C++
慕森王 2019-08-30 17:43:54
我正在查看.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中的函数。我希望这个问题有道理,我再也不会咆哮一些错误的树了。
查看完整描述

2 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

LoadLibrary不会做你认为它做的事情。它加载DLL到当前进程的内存,但它并不会神奇地导入它定义的功能!这是不可能的,因为LoadLibrary在运行时调用时,链接器会在编译时解析函数调用(请记住,C ++是一种静态类型语言)。


您需要一个单独的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;

}

此外,您应该正确地从DLL 导出您的函数。这可以这样做:


int __declspec(dllexport) __stdcall funci() {

   // ...

}

正如Lundin指出的那样,如果您不再需要它,那么将句柄释放到库中是一种很好的做法。如果没有其他进程仍然拥有同一DLL的句柄,这将导致它被卸载。


查看完整回答
反对 回复 2019-08-30
  • 2 回答
  • 0 关注
  • 696 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信