Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 快速一个:结构成员的GetProcAddress?_C++_Getprocaddress - Fatal编程技术网

C++ 快速一个:结构成员的GetProcAddress?

C++ 快速一个:结构成员的GetProcAddress?,c++,getprocaddress,C++,Getprocaddress,假设我对DLL中的结构有以下定义: typedef struct { double varOne; double varTwo; } structOne; structOne myStruct; 然后可以从加载DLL的主应用程序执行以下操作: structOne * sPtr = (structOne *)GetProcAddress(libraryHandle, "myStruct"); 我的问题是,是否有可能采取以下措施: double * dPtr = (double

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

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

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

structOne * sPtr = (structOne *)GetProcAddress(libraryHandle, "myStruct");
我的问题是,是否有可能采取以下措施:

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

问候并希望得到答案

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

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

,事实上这是不可能的,因为使用GetProcAddress访问的函数(符号)仅由

事实上,这是不可能的,因为使用GetProcAddress访问的函数(符号)仅由导出的函数(符号)

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

为了解决您的问题,您可以从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导出添加到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)();

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

为了解决您的问题,您可以从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导出添加到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)();
偏移量本身(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)
};
偏移量本身(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)
};

我认为您误解了应用程序如何使用dll中的代码。应用程序在自己的ram中创建dll中结构的本地副本。所有这些都是豆荚。执行代码(即函数)也是如此,它们位于可执行文件的相同地址空间中。因此,整个“LoadLibrary”调用,它将DLL的内容物理加载到您的模块(exe)地址空间中。答案在哪里?不幸的是,无法进行否决表决。我认为您误解了应用程序如何使用dll中的代码。应用程序在自己的ram中创建dll中结构的本地副本。所有这些都是豆荚。执行代码(即函数)也是如此,它们位于可执行文件的相同地址空间中。因此,整个“LoadLibrary”调用,它将DLL的内容物理加载到您的模块(exe)地址空间中。答案在哪里?不幸的是,不可能进行向下投票。此信息当然在运行时存在,但不会通过导出地址表导出。一旦在运行时有指向structOne符号的指针,就可以访问此信息。有关偏移量的信息仅隐式地存在于exe/dll模块中。此信息当然在运行时存在,但不会通过导出地址表导出。在运行时,只要有指向structOne符号的指针,就可以访问此信息。有关偏移量的信息仅隐式地存在于exe/dll模块中。我只想指出,在我当前的设置(在问题中简化了)中,获取结构本身并不是问题-这非常有效,即使没有这里介绍的包装器函数。问题是,我需要直接访问结构的成员,如果能够通过带名称的字符串访问它们,而不是将实际符号硬编码到主应用程序中,那将非常方便……我只想注意,在我当前的设置中(在问题中简化了)获取结构本身并不是问题所在——即使没有这里介绍的包装器函数,它也能很好地工作。问题是,我需要直接访问结构的成员,如果能够通过带名称的字符串访问它们,而不是将实际符号硬编码到主应用程序中,那将非常方便。。。