无法使用 GetProcAddress 获取 dll 函数的地址

发布于 2024-09-14 16:52:12 字数 2162 浏览 5 评论 0原文

我用 VS C++ 创建了一个 dll(当然作为一个 dll 项目),头文件的代码如下:

#pragma once
#include <iostream>
#include "..\..\profiles/ProfileInterface.h"

using namespace std;

extern "C" __declspec(dllexport) class CExportCoordinator: public CProfileInterface
{
public:
    CExportCoordinator(void);
    virtual ~CExportCoordinator(void);
    
    CProfileInterface* Create();
    void Initialize();
    void Start();   
};

这是 dll 的 .cpp 文件:

#include "StdAfx.h"
#include "ExportCoordinator.h"

CExportCoordinator::CExportCoordinator(void)
{
}

CExportCoordinator::~CExportCoordinator(void)
{
}

CProfileInterface* CExportCoordinator::Create(){
    
    cout << "ExportCoordinator3 created..." << endl;
    return new CExportCoordinator();
}

void CExportCoordinator::Initialize(){

        cout << "ExportCoordinator3 initialized..." << endl;
}

void CExportCoordinator::Start(){
    
    cout << "ExportCoordinator3 started..." << endl;
}

我导出了整个类 CExportCoordinator 因为我需要使用它提供的所有三种方法。以下是来自主应用程序的代码,动态加载上面给出的 dll。

    typedef CProfileInterface* (WINAPI*Create)();
    
    int _tmain(int argc, _TCHAR* argv[])

{    
    HMODULE hLib = LoadLibrary(name);
    

    if(hLib==NULL) {
        cout << "Unable to load library!" << endl;         
        return NULL;
    }
    char mod[MAXMODULE];
    
    GetModuleFileName(hLib, (LPTSTR)mod, MAXMODULE);
    cout << "Library loaded: " << mod << endl;   
        
    Create procAdd = (Create) GetProcAddress(hLib,"Create");
        
    if (!procAdd){
        cout << "function pointer not loaded";
    }
    return;
}

在输出中,我得到正确的库已加载,但函数指针 procAdd 为 NULL。我认为这与名称修改有关,并在导出 dll 标头中的类时添加了 extern "C" ,但没有任何改变。顺便说一句,我使用 dll 导出查看器 来查看类的导出函数,以及整个班级已正确导出。 有什么帮助吗?

更新
dll的头文件有错误。我不应该在上课前使用 extern "C" __declspec(dllexport) ,因为这样根本不会导出类。如果我使用 class __declspec(dllexport) CExportCoordinator 则该类将正确导出,但无论如何我无法获取除 NULL 之外的函数地址。

I created a dll with VS C++ (of course as a dll project) with the following code of the header file:

#pragma once
#include <iostream>
#include "..\..\profiles/ProfileInterface.h"

using namespace std;

extern "C" __declspec(dllexport) class CExportCoordinator: public CProfileInterface
{
public:
    CExportCoordinator(void);
    virtual ~CExportCoordinator(void);
    
    CProfileInterface* Create();
    void Initialize();
    void Start();   
};

Here is .cpp file of the dll:

#include "StdAfx.h"
#include "ExportCoordinator.h"

CExportCoordinator::CExportCoordinator(void)
{
}

CExportCoordinator::~CExportCoordinator(void)
{
}

CProfileInterface* CExportCoordinator::Create(){
    
    cout << "ExportCoordinator3 created..." << endl;
    return new CExportCoordinator();
}

void CExportCoordinator::Initialize(){

        cout << "ExportCoordinator3 initialized..." << endl;
}

void CExportCoordinator::Start(){
    
    cout << "ExportCoordinator3 started..." << endl;
}

I exported the whole class CExportCoordinator because I need to use all three methods it offers. Following is the code from the main application loading the, above given, dll on the fly.

    typedef CProfileInterface* (WINAPI*Create)();
    
    int _tmain(int argc, _TCHAR* argv[])

{    
    HMODULE hLib = LoadLibrary(name);
    

    if(hLib==NULL) {
        cout << "Unable to load library!" << endl;         
        return NULL;
    }
    char mod[MAXMODULE];
    
    GetModuleFileName(hLib, (LPTSTR)mod, MAXMODULE);
    cout << "Library loaded: " << mod << endl;   
        
    Create procAdd = (Create) GetProcAddress(hLib,"Create");
        
    if (!procAdd){
        cout << "function pointer not loaded";
    }
    return;
}

On the output I get that correct library is loaded, but that function pointer procAdd is NULL. I thought it had something to do with name mangling and added extern "C" when exporting the class in header of dll, but nothing changed. Btw, I used dll export viewer for viewing the exported functions of the class, and the whole class is exported correctly.
Any help?

UPDATE
there is an error in the header file of dll. I shouldn't be using extern "C" __declspec(dllexport) before class because then class won't be exported at all. If I use class __declspec(dllexport) CExportCoordinator then the class is exported correctly, but anyway I can't get the address of the function other than NULL.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苦行僧 2024-09-21 16:52:12
extern "C" __declspec(dllexport) class CExportCoordinator: public CProfileInterface 
{ 

这是无稽之谈。类不能是“extern C”

... inside the class ...
    CProfileInterface* Create();  

这会创建该类的成员函数,这可能不是您想要的。一方面,它将在 DLL 中被破坏,其次,如果没有 this 指针,它将无法调用。也许,您需要这个声明:

extern "C" __declspec(dllexport) CProfileInterface* Create();  

和实现:

extern "C" __declspec(dllexport) CProfileInterface* Create(){
    cout << "ExportCoordinator3 created..." << endl;     
    return new CExportCoordinator();     
}   
extern "C" __declspec(dllexport) class CExportCoordinator: public CProfileInterface 
{ 

This is nonsense. A class cannot be "extern C"

... inside the class ...
    CProfileInterface* Create();  

This creates a member function of the class, which is not probably what you want. For one thing, it will be mangled in the DLL, second, it will not be callable without the this pointer. Probably, you need this declaration:

extern "C" __declspec(dllexport) CProfileInterface* Create();  

and implemntation:

extern "C" __declspec(dllexport) CProfileInterface* Create(){
    cout << "ExportCoordinator3 created..." << endl;     
    return new CExportCoordinator();     
}   
东风软 2024-09-21 16:52:12

在我看来,您应该将 Create 方法声明为 static 方法并仅导出此方法。如果您在 GetProcAddress 中保留 NULL,则应检查 DLL 的导出是否符合 Dependency Walker(请参阅 http://www.dependencywalker.com/) 并将函数“Create”的名称修改为“_Create”或“_Create@2”之类的名称。

It seems to me that you should declare Create method as a static method and export this method only. If you will stay have NULL in GetProcAddress you should examine exports of your DLL with respect of Dependency Walker (see http://www.dependencywalker.com/) and modify the name of the function "Create" to something like "_Create" or "_Create@2".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文