首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回空的GetProcAddress函数

返回空的GetProcAddress函数
EN

Stack Overflow用户
提问于 2017-01-04 10:01:58
回答 2查看 3.8K关注 0票数 1

尝试动态加载C++动态链接库,首先使用"LoadLibrary“函数加载dll,并正确获取句柄。之后,我尝试使用"GetProcAddress“获取DLL文件函数的函数指针,它将返回NULL。请找到我的DLL代码和测试应用程序代码,并让我知道哪里是错误的代码。

dummy2.h

代码语言:javascript
复制
namespace newer
{
  class dllclass
  {
    public:
        static __declspec(dllexport) int run(int a,int b);
  };
}

dummy2.cpp

代码语言:javascript
复制
#include <iostream>
using namespace std;

#include "dummy2.h"

namespace newer
{
  int dllclass::run(int a,int b)
  {
    return a+b;
  }
}

dummy1.cpp

代码语言:javascript
复制
#include "stdafx.h" 
#include <windows.h>

#include <iostream>
using namespace std;
typedef int (*Addition)(int,int);

int _tmain(int argc, _TCHAR* argv[])
{
  Addition add;
  HINSTANCE hDLL;
  hDLL = LoadLibrary(TEXT("Dummy2.dll"));

  add = (Addition)GetProcAddress(hDLL, "run");  

  getchar();
  return 0;
}

请参考以上代码并指导我。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-04 10:14:35

这是因为名称是错误的(即函数的名称不是"run“,而是一些不同的东西)。

您的代码将用于(我测试的MSVC 2013 ):

代码语言:javascript
复制
add = (Addition)GetProcAddress(hDLL, "?run@dllclass@newer@@SAHHH@Z");
cout << add(1, 2) << endl;

通常,如果您想通过插件加载类,最好的方法是使用虚拟接口。举个例子:

代码语言:javascript
复制
//dummy2.h
namespace newer
{
  class dllclass_interface
  {
    public:
        virtual int run(int a,int b) = 0;
 };

}

extern "C" __declspec(dllexport) newer::dllclass_interface* getDllClass();
代码语言:javascript
复制
//dummy2.cpp
#include <iostream>
using namespace std;

#include "dummy2.h"

namespace newer
{
  class dllclass: public dllclass_interface
  {
    public:
        virtual int run(int a,int b);
 };

  int dllclass::run(int a,int b)
  {
    return a+b;
  }
}

extern "C" newer::dllclass_interface* getDllClass()
{
    static newer::dllclass instance;
    return &instance;
}
代码语言:javascript
复制
typedef newer::dllclass_interface* (*GetClassFunc)();

GetClassFunc getClassFunc = (GetClassFunc)GetProcAddress(hDLL, "getDllClass");

newer::dllclass_interface* dllClass = getClassFunc();
cout << dllClass->run(a, b) << endl;
票数 7
EN

Stack Overflow用户

发布于 2017-01-04 10:10:31

实际上,DLL是在C时代引入的,从那时起,C++引入了函数名重载(取决于参数的类型),以及一些称为“错误名称”的东西,以允许以正确的名称链接函数调用。C++标准没有指定这个名称应该是什么样的。不同的编译器以不同的方式实现了参数的嵌入类型。

C++理解这个问题,有时需要有可预测的名称。在C++中有一个特殊的构造:

代码语言:javascript
复制
extern "C"
{
     int run(int, int);
}

当在GetProcAddress中指定函数的名称时,它应该与从DLL导出的函数完全相同。您可以使用像DependencyWalker这样的特殊实用程序来查看这些名称。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41461019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档