猿问

从DLL动态加载函数

我正在查看.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中的函数。


我希望这个问题有道理,我再也不会咆哮一些错误的树了。


慕森王
浏览 697回答 2
2回答

慕勒3428872

LoadLibrary不会做你认为它做的事情。它加载DLL到当前进程的内存,但它并不会神奇地导入它定义的功能!这是不可能的,因为LoadLibrary在运行时调用时,链接器会在编译时解析函数调用(请记住,C ++是一种静态类型语言)。您需要一个单独的WinAPI函数来获取动态加载函数的地址:GetProcAddress。例#include <windows.h>#include <iostream>/* Define a function pointer for our imported&nbsp;* function.&nbsp;* This reads as "introduce the new type f_funci as the type:&nbsp;&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pointer to a function returning an int and&nbsp;&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; taking no arguments.&nbsp;*&nbsp;* Make sure to use matching calling convention (__cdecl, __stdcall, ...)&nbsp;* with the exported function. __stdcall is the convention used by the WinAPI&nbsp;*/typedef int (__stdcall *f_funci)();int main(){&nbsp; HINSTANCE hGetProcIDDLL = LoadLibrary("C:\\Documents and Settings\\User\\Desktop\\test.dll");&nbsp; if (!hGetProcIDDLL) {&nbsp; &nbsp; std::cout << "could not load the dynamic library" << std::endl;&nbsp; &nbsp; return EXIT_FAILURE;&nbsp; }&nbsp; // resolve function address here&nbsp; f_funci funci = (f_funci)GetProcAddress(hGetProcIDDLL, "funci");&nbsp; if (!funci) {&nbsp; &nbsp; std::cout << "could not locate the function" << std::endl;&nbsp; &nbsp; return EXIT_FAILURE;&nbsp; }&nbsp; std::cout << "funci() returned " << funci() << std::endl;&nbsp; return EXIT_SUCCESS;}此外,您应该正确地从DLL 导出您的函数。这可以这样做:int __declspec(dllexport) __stdcall funci() {&nbsp; &nbsp;// ...}正如Lundin指出的那样,如果您不再需要它,那么将句柄释放到库中是一种很好的做法。如果没有其他进程仍然拥有同一DLL的句柄,这将导致它被卸载。
随时随地看视频慕课网APP
我要回答