1

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

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

structOne myStruct;

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

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

我的问题是是否有可能做一些类似的事情:

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

问候并希望得到答案!

4

4 回答 4

3

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

于 2012-06-26T11:05:21.250 回答
1

如其他答案所述,这是不可能的。

为了解决您的问题,您可以从 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)();
于 2012-06-26T11:18:45.710 回答
1

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

于 2012-06-26T11:07:48.800 回答
0

偏移量本身 (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)
};
于 2012-06-26T12:22:50.347 回答