1

Let's say I have the following definition of a struct in a DLL:

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

structOne myStruct;

It is then possible to do the following from the main application which loads the DLL:

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

My question is if it would be possible to do something of the likes of:

double * dPtr = (double *)GetProcAddress(libraryHandle, "myStruct.varOne");
  • If you understand what I want and it is possible; what is the syntax?
  • If it is not possible; why?
  • If you do not understand my question; say so in a comment!

Regards and hopeful for answers!

mloskot
  • 37,086
  • 11
  • 109
  • 136
Stonegoat
  • 73
  • 5
  • 1
    I think you misunderstand how the code in the dll is used by your application. Your application creates a local copy in it's own ram of the structure that's in the dll. All that is POD. Same goes with execution code (ie function) they reside in the same address space of your executable. Hence the whole "LoadLibrary" call, it physically loads the contents of the DLL into your module(exe's) address space. – johnathan Jun 26 '12 at 11:06
  • Where is the answer? Unfortunately it is not possible to downvote. – Kirill Kobelev Jun 26 '12 at 11:11

4 Answers4

3

No, this is not possible. GetProcAddress has access only to the dynamic linker info. Information about the layout of the classes/structures is part of the compiler info. Compiler places this info into PDB files. It is not directly present in the binary modules. GetProcAddress has access only to the info that is stored in the EXE/DLL files. PDB files are primarily used by debuggers with a really few exceptions like StackWalk.

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
  • This info is of course present at runtime, but, it is not exported by the Export Address Table. This info is accessible once you have a pointer to the structOne Symbol, at runtime. – mox Jun 26 '12 at 11:11
  • Info about offsets is present only implicitly in the exe/dll module. – Kirill Kobelev Jun 26 '12 at 11:14
1

As matter of fact it is NOT possible, BECAUSE the Functions (Symbols) accessible using GetProcAddress are ONLY the one exported by the Export Address Table!

mox
  • 6,084
  • 2
  • 23
  • 35
1

As mentioned in other answers, this is not possible.

To solve your problem, you could export the struct definition from the DLL, export a global function that returns the address of your global variable. From the exe, import this function and call this to get the pointer to the global struct object defined in the dll. Code follows...

Add a structOne.h file and move the structure definition to that file. Modify the definition as this

#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif

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

Add the C++ pre-processor macro TESTDLL_EXPORTS to your DLL.

define a global function like this in the structOne.cpp file and export it too.

structOne myStruct; // your global variable

TESTDLL_API structOne* getStruct(){return &myStruct;}

Then build the DLL.

From the .exe, use the following code to call the method. Also, include the structOne.h header file

typedef structOne* (*getStruct)();

HMODULE libraryHandle = ::LoadLibraryA("TestDLL.dll");
getStruct fn = (getStruct)::GetProcAddress(libraryHandle, "getStruct");
structOne* s = (*fn)();
PermanentGuest
  • 5,213
  • 2
  • 27
  • 36
  • I just want to note that with my current setup (which is simplified in the question) getting the struct itself is not the problem - that works beautifully, even without a wrapper function which was presented here. The problem is that I need direct access to the members of the struct and it would have been _very_ convenient to be able to access them by a string with their name instead of hard coding the actual symbol in to the main application... – Stonegoat Jun 26 '12 at 11:33
0

The offset itself (0) is implicitly present in the DLL, but the symbol corresponding to that offset (".varOne") isn't.

Workaround:

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)
};
MSalters
  • 173,980
  • 10
  • 155
  • 350