【问题标题】:Quick one: GetProcAddress of Struct member?快速一:Struct成员的GetProcAddress?
【发布时间】:2012-06-26 11:01:40
【问题描述】:

假设我在 DLL 中有以下结构的定义:

typedef struct {
    double varOne;
    double varTwo;
} structOne;

structOne myStruct;

然后可以从加载 DLL 的主应用程序执行以下操作:

structOne * sPtr = (structOne *)GetProcAddress(libraryHandle, "myStruct");

我的问题是如果可以做一些类似的事情:

double * dPtr = (double *)GetProcAddress(libraryHandle, "myStruct.varOne");
  • 如果你明白我想要什么并且这是可能的;语法是什么?
  • 如果不可能;为什么?
  • 如果您不理解我的问题;在评论中说出来!

问候并希望得到答案!

【问题讨论】:

  • 我认为您误解了您的应用程序如何使用 dll 中的代码。您的应用程序在它自己的 dll 中结构的内存中创建一个本地副本。这就是POD。执行代码(即函数)也是如此,它们驻留在可执行文件的相同地址空间中。因此,整个“LoadLibrary”调用,它将 DLL 的内容物理加载到您的模块(exe)地址空间中。
  • 答案在哪里?很遗憾,无法投反对票。

标签: c++ getprocaddress


【解决方案1】:

不,这是不可能的。 GetProcAddress 只能访问动态链接器信息。有关类/结构布局的信息是编译器信息的一部分。编译器将此信息放入 PDB 文件中。它不直接存在于二进制模块中。 GetProcAddress 只能访问存储在 EXE/DLL 文件中的信息。 PDB 文件主要由调试器使用,只有少数例外,例如 StackWalk

【讨论】:

  • 此信息在运行时当然存在,但它不会由导出地址表导出。一旦您在运行时拥有指向 structOne 符号的指针,就可以访问此信息。
  • 关于偏移量的信息仅隐含在 exe/dll 模块中。
【解决方案2】:

事实上这是不可能的,因为使用 GetProcAddress 可访问的函数(符号)只是 Export Address Table 导出的函数(符号)!

【讨论】:

    【解决方案3】:

    正如其他答案中提到的,这是不可能的。

    要解决您的问题,您可以从 DLL 中导出结构定义,导出一个返回全局变量地址的全局函数。从 exe 中导入此函数并调用此函数以获取指向 dll 中定义的全局结构对象的指针。代码如下...

    添加一个 structOne.h 文件并将结构定义移动到该文件。修改定义为这样

    #ifdef TESTDLL_EXPORTS
    #define TESTDLL_API __declspec(dllexport)
    #else
    #define TESTDLL_API __declspec(dllimport)
    #endif
    
    struct TESTDLL_API structOne{
        double varOne;
        double varTwo;
    } ;
    

    将 C++ 预处理器宏 TESTDLL_EXPORTS 添加到您的 DLL。

    在 structOne.cpp 文件中定义一个这样的全局函数并将其也导出。

    structOne myStruct; // your global variable
    
    TESTDLL_API structOne* getStruct(){return &myStruct;}
    

    然后构建 DLL。

    从 .exe 中,使用以下代码调用该方法。 另外,包括 structOne.h 头文件

    typedef structOne* (*getStruct)();
    
    HMODULE libraryHandle = ::LoadLibraryA("TestDLL.dll");
    getStruct fn = (getStruct)::GetProcAddress(libraryHandle, "getStruct");
    structOne* s = (*fn)();
    

    【讨论】:

    • 我只想指出,使用我当前的设置(在问题中进行了简化),获取结构本身并不是问题 - 即使没有此处提供的包装函数,它也可以很好地工作。问题是我需要直接访问结构的成员,如果能够通过带有名称的字符串访问它们,而不是将实际符号硬编码到主要应用...
    【解决方案4】:

    偏移量本身 (0) 隐含在 DLL 中,但对应于该偏移量 (".varOne") 的符号 不存在。

    解决方法:

    struct member_t { char const* type; char const* member; size_t offset };
    #define MEMBER(T, M) {#T, #M, offset_of(T, M) }
    member_t exports[] = {
      MEMBER(myStruct, varOne)
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-09
      • 2020-04-03
      • 2019-09-07
      • 2012-03-08
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多