Witam,
Piszę aplikację w C++, która korzysta z bibliotek dll i mam problem z dostępem do zmiennych globalnych dllki ale tylko przy kompilacji 64 bitowej.
Przykładowy kod aplikacji głównej
// dostępne również w bibliotece DLL
typedef struct InfoStruct
{
int Size;
char* name;
}LoadStruct;
typedef struct LoadStruct
{
int (__stdcall *DoAction)( InfoStruct* );
}LoadStruct;
extern "C" int __stdcall DoAction(InfoStruct* info)
{
printf(L"%d [%s]", info->Size, info->name);
return 0;
}
LoadStruct LoadData;
HINSTANCE hDll;
int Load(char* DllPath)
{
hDll = LoadLibrary( DllPath );
typedef int( __stdcall * LoadPROC )( LoadStruct* );
LoadPROC proc;
if( hDll != NULL )
{
proc = ( LoadPROC )GetProcAddress( hDll, "Load" );
if(!proc)
return 0;
LoadData.DoAction = &DoAction;
if(!proc(&LoadData)) // przekazuję strukturę z adresem funkcji DoAction
return 0;
}
return 1;
}
Oraz kod biblioteki DLL
LoadStruct* LoadData;
InfoStruct InfoData;
extern "C" int __stdcall Load(LoadStruct* _LoadData)
{
LoadData = _LoadData;
return 1;
}
int JakasFunkcja()
{
InfoData.Size = 5;
InfoData.name = "nazwa";
return LoadData->DoAction(&InfoData);
}
Podczas gdy wywołanie funkcji "JakasFunkcja" na 32 bitach nie robi problemu to na 64bitach dostaję Access violation.
Ale już takie kody(DLL) działają bez problemu
// pierwszy
int JakasFunkcja()
{
InfoStruct InfoData;
InfoData.Size = 5;
InfoData.name = "nazwa";
return LoadData->DoAction(&InfoData);
}
// drugi
InfoStruct* InfoData = NULL;
int JakasFunkcja()
{
if(!InfoData)
InfoData = new InfoStruct;
InfoData->Size = 5;
InfoData->name = "nazwa";
return LoadData->DoAction(&InfoData);
}
Wychodzi na to, że aplikacja nie ma dostępu do zmiennej globalnej biblioteki ale według MSDN każda aplikacja główna otrzymuje własną kopię zmiennych globalnych
Variables that are declared as global in a DLL source code file are treated as global variables by the compiler and linker, but each process that loads a given DLL gets its own copy of that DLL's global variables. The scope of static variables is limited to the block in which the static variables are declared. As a result, each process has its own instance of the DLL global and static variables by default.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682594%28v=vs.85%29.aspx
I teraz jest pytanie, czy DLL nie może przesyłać adresu do zmiennej globalnej zadeklarowanej w sobie? Przypomnę, że dla aplikacji 32bitowej działa poprawnie.