Jump to content
  • Advertisement
Sign in to follow this  
b1gjo3

dll initializing

This topic is 3646 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

ok so i have this dll application which runs an instance of this dll provided below. the problem i am having is that this dll seems to keep getting re-initialized whenever i select over to another window process. thus, the filepath variable i set by using my main exe program is not initialized by all later calls from other processes. how can i stop this dll from being initialized more than once? .dll file
#include <windows.h>
#include <CharFunc.h>
#include <iostream>
#include <fstream>

#pragma data_seg("SharedBlock")
	HINSTANCE	hInst = NULL;
	HHOOK		keyHook = NULL;
	FILE*		file1 = NULL;
	char*		filepath = NULL;
	int	        hookState = -1;
#pragma data_seg()

extern "C" __declspec (dllexport) int _stdcall GetHookState()
{
	return hookState;
}

extern "C" __declspec (dllexport) int _stdcall AppendToLog(char* append)
{
	fopen_s(&file1, filepath, "a");
	fwrite(append, 1, strlen(append), file1);
	fclose(file1);
	return 0;
}

extern "C" __declspec (dllexport) LRESULT CALLBACK __stdcall KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
	if ( (code < 0) || (wParam == VK_CONTROL) || (wParam >= VK_F1 && wParam <= VK_F11))
		return CallNextHookEx(keyHook, code, wParam, lParam);

	if (code == HC_ACTION)
	{
		if( (GetKeyState(VK_SHIFT) & 0x8000) != 0)
			shiftState = true;
		else
			shiftState = false;

		if ((HIWORD(lParam) & KF_UP) == 0)
		{
			MessageBox(NULL, ConvertCharToWide(filepath), TEXT("FilePath"), MB_OK);
			fopen_s(&file1, filepath, "a");

                        count++;
                        //..output int to file
                       
			fclose(file1);
		}//end key up
	}//end if (code == HC_ACTION)
	return  CallNextHookEx(keyHook, code, wParam, lParam);	
}

extern "C" int __declspec (dllexport) __stdcall SetKeyboardHook(char* fpath)
{
	//set the keyboard hook
	keyHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInst, 0); 

	if (keyHook == NULL)
	{
		//MessageBox(NULL, TEXT("Could Not Set Hook"), TEXT("Error #003"), NULL);
		hookState = -1;
		return -1;
	}
	else
	{
		filepath = new char[strlen(fpath) + 1];
		strcpy_s(filepath, strlen(fpath) + 2, fpath);
		//MessageBox(NULL,TEXT("Hooked"),TEXT("Hookoed"),MB_OK);
		hookState = 0;
		return 0;
	}
}

extern "C" int __declspec (dllexport) __stdcall UnsetKeyboardHook()
{
	//unhook
	UnhookWindowsHookEx(keyHook);

	if (filepath != NULL)
		delete [] filepath;

	hookState = -1;
	//MessageBox(NULL,TEXT("Unhooked"),TEXT("Unhooked"),MB_OK);
	return 0;
}

extern "C" BOOL __declspec (dllexport) __stdcall DllMain (HINSTANCE hInstance, DWORD reason, LPVOID reserved)
{
	switch (reason)
	{
		case DLL_PROCESS_ATTACH:
		{
			//save instance
			hInst = hInstance;
			MessageBox(NULL,TEXT("Attached"),TEXT("Attached"),MB_OK);
			break;
		}
		case DLL_PROCESS_DETACH:
		{
			MessageBox(NULL,TEXT("Detached"),TEXT("Detached"),MB_OK);
			break;
		}
    }
    return TRUE;
}

Share this post


Link to post
Share on other sites
Advertisement
Mark the section as shared. Add the folling after your #pragma data_seg() line:
#pragma comment(linker, "/section:SharedBlock,RWS")

Share this post


Link to post
Share on other sites
what exactly does that line do? also, for some reason the program works if i put in a string constant such as "C:\\Users\\BigJoe\\Desktop\\fab.txt". but when i copy that into the filepath variable it just doesnt work. also when i specify the filepath variable, im not even getting the messagebox i built into the keyboardproc.

what could be going on?

Share this post


Link to post
Share on other sites
By default each process loads a different 'instance' of a dll in it's own address space which is why setting a value in one won't be reflected in the others, unless such value is set to a variable that is into a section marked as shared

Share this post


Link to post
Share on other sites
Quote:
Original post by b1gjo3
ok, is there any reason why the application still wont work with the #pragma line?
Each EXE has it's own heap, and they can't easily share information that way. I'd make the string a static sized buffer, of say 512 bytes, then just copy into that. Then there's no memory allocation going on, so the different heaps don't matter.

Share this post


Link to post
Share on other sites
that did the trick! i dont really understand why because i didnt think there was much difference between..

char filepath[MAX_PATH] = {}
char* filepath = new char[MAX_PATH];

Share this post


Link to post
Share on other sites
Quote:
Original post by b1gjo3
that did the trick! i dont really understand why because i didnt think there was much difference between..

char filepath[MAX_PATH] = {}
char* filepath = new char[MAX_PATH];
The first one allocates MAX_PATH characters on the stack or .data segment, the second allocates MAX_PATH characters from the heap.

In your DLL, the .data segment is shared, so that memory for filepath is shared, but the heap isn't shared (And there's no way to share it between processes).


When a DLL is loaded by an EXE, you can think of it as copying everything in the DLL into the EXE. Because of that, each EXE gets its own heap, and can't access each others. Your shared segment means it's shared between all EXEs that load it, meaning the variable is shared. In the second case, only the pointer is shared, and it doesn't point to anywhere useful - it'd be like getting a pointer, and then telling someone the address for them to use that memory in another program; it just won't work.

Share this post


Link to post
Share on other sites
Ok, listen carefully

Each executable has it's own heap, which is where "new" allocates memory from.

You tagged "filepath" as a shared location, using the #pragma directive. "filepath" is of type "char*", therefore you are sharing 4 bytes (let's assume that the size of a pointer is 4 bytes) between all the instances of your dll.

Now, when you run your first executable, "new char[MAX_PATH]" allocates a memory buffer of "MAX_PATH * sizeof(char)" bytes IN THE HEAP OF THIS EXECUTABLE. Therefore, "filepath" stores the address of that buffer IN THE HEAP OF THIS EXECUTABLE.

Then you run your second executable, which in turns loads a new instance of your dll. "filepath" is already initialized, with an address of a memory buffer into another process's heap. Since each process has it's own address space, this is totally illegal, and you program will exhibit undefined behavior.

In conlusion, if you want to share the whole char array, you need to tag a whole char array as shared like Evil Steve said.

Hope that helps..
JA

Edit: geez.. beaten :/

Share this post


Link to post
Share on other sites
Quote:
Original post by janta
Edit: geez.. beaten :/


hah.. anyways i think you both helped me to understand this problem. I do appreciate your help and its working fine now. much much appreciation guys.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!