2012-06-26 3 views
0

의 내가이 DLL의 구조체의 다음과 같은 정의가 있다고 가정 해 봅시다빠른 하나 : 구조체 멤버의 GetProcAddress?</p> <pre><code>typedef struct { double varOne; double varTwo; } structOne; structOne myStruct; </code></pre> <p>그것은 <em>이 (가) DLL로드의 주요 응용 프로그램에서 다음을 수행하는 것이 가능</em> 다음과 같습니다 :

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

내 질문이 이면과 같은 것을 할 수 있습니다.

  • 내가 원하는 것을 이해하면 가능합니다. 구문은 무엇입니까?
  • 가능하지 않은 경우; 왜?
  • 내 질문을 이해하지 못하는 경우; 의견에서 그렇게 말하십시오!

답변에 대한 답변과 희망!

+1

난 당신이 DLL의 코드는 응용 프로그램에서 사용되는 방법을 오해 생각합니다. 응용 프로그램은 dll에있는 구조의 자체 RAM에 로컬 사본을 만듭니다. POD입니다. 실행 파일의 동일한 주소 공간에 상주하는 실행 코드 (즉 함수)도 마찬가지입니다. 따라서 전체 "LoadLibrary"호출은 DLL의 내용을 모듈 (exe)의 주소 공간에 물리적으로로드합니다. – johnathon

+0

답변은 어디에 있습니까? 불행히도 downvote는 불가능합니다. –

답변

3

아니요, 불가능합니다. GetProcAddress은 동적 링커 정보에만 액세스 할 수 있습니다. 클래스/구조의 레이아웃에 대한 정보는 컴파일러 정보의 일부입니다. 컴파일러는이 정보를 PDB 파일에 저장합니다. 바이너리 모듈에는 직접 존재하지 않습니다. GetProcAddress은 EXE/DLL 파일에 저장된 정보에만 액세스 할 수 있습니다. PDB 파일은 주로 StackWalk과 같은 몇 가지 예외가있는 디버거에서 주로 사용됩니다.

+0

이 정보는 물론 런타임에는 표시되지만 내보내기 주소 표에서는 내보내지지 않습니다. 이 정보는 런타임에 structOne Symbol에 대한 포인터가 있으면 액세스 할 수 있습니다. – mox

+0

오프셋에 대한 정보는 exe/dll 모듈에만 제공됩니다. –

+0

정확하고이 코드는 런타임에 사용할 수 있습니다. – mox

1

사실 GetProcAddress를 사용하여 액세스 할 수있는 기능 (기호)은 Export Address Table에서 내 보낸 것일뿐입니다!

1

다른 답변에서 언급했듯이 이것은 불가능합니다.

문제를 해결하려면 DLL에서 구조체 정의를 내 보낸 다음 전역 변수의 주소를 반환하는 전역 함수를 내 보내면됩니다. exe에서이 함수를 임포트하고 이것을 호출하여 dll에 정의 된 전역 struct 객체에 대한 포인터를 얻습니다. 코드는 다음과 같습니다 ...

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; 
} ; 

DLL에 C++ 사전 처리기 매크로 TESTDLL_EXPORTS를 추가하십시오.

이와 비슷한 전역 함수를 structOne.cpp 파일에 정의하고 내보내십시오.

structOne myStruct; // your global variable 

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

그런 다음 DLL을 빌드하십시오.

.exe에서 다음 코드를 사용하여 메서드를 호출합니다. 는 또한 자체 (0) DLL 내재적 존재 오프셋되지만 심볼 그 오프셋 (".varOne")에 대응하지 않은 structOne.h 헤더 파일

typedef structOne* (*getStruct)(); 

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

그냥 (질문에 단순화되어있는) 현재의 설정으로 구조체 자체를 얻는 것이 문제가 아니라는 점을 기억하고 싶습니다. 여기에 제시된 래퍼 함수가 없어도 아름답게 작동합니다. 문제는 구조체의 멤버에 직접 액세스해야한다는 것이고 주 응용 프로그램에 실제 기호를 하드 코딩하는 대신 이름에 문자열을 사용하여 액세스 할 수 있으면 편리하다는 것입니다. – Stonegoat

0

을 포함한다.

해결 방법 :

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) 
};