假设我在DLL中有以下结构定义:
typedef struct {
double varOne;
double varTwo;
} structOne;
structOne myStruct;
然后可以从加载DLL的主应用程序执行以下操作:
structOne * sPtr = (structOne *)GetProcAddress(libraryHandle, "myStruct");
我的问题是如果可以做以下的事情:
double * dPtr = (double *)GetProcAddress(libraryHandle, "myStruct.varOne");
关心并希望得到答案!
答案 0 :(得分:3)
不,这是不可能的。 GetProcAddress
只能访问动态链接器信息。有关类/结构布局的信息是编译器信息的一部分。编译器将此信息放入PDB文件中。它不直接存在于二进制模块中。 GetProcAddress
只能访问存储在EXE / DLL文件中的信息。 PDB文件主要由调试器使用,只有很少的例外,如StackWalk
。
答案 1 :(得分:1)
事实上它是不可能的,因为使用GetProcAddress可访问的函数(符号)只是由Export Address Table导出的函数(
)。答案 2 :(得分: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)();
答案 3 :(得分: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)
};