Ok, I have a DLL I made. In the DllMain function, I have a variable called my_var (const char[13]). I compiled the dll (called "WGCL") and put it in the debug directory of my Win32 Project. I used /DELAYLOAD:WGCL.dll to Delay Load the DLL which seems to be the only way to link the library. It loads the DLL fine and there is no errors or warnings. But when I try to use the variable (which is in the DllMain section), it says it doesnt exist. So obviously the compiler cannot access the variable from DllMain because it has not been properly exported, how can I export the variable? I have tried extern "C", and extern "C" PASCAL EXPORT. How do I export this variable for use in my Win32 Project?

This is how it looks:

WGCL DLL Proj. - WGCL.cpp

#include "stdafx.h"

#ifdef _MANAGED
  #pragma managed(push, off)
#endif

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    const char my_var[13] = "Hello World!";

    return TRUE;
}

#ifdef _MANAGED
  #pragma managed(pop)
#endif

WGCL Win32 EXE Proj. - WGCL Test.cpp

#include "stdafx.h"
#include "WGCL Test.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name

// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_WGCLTEST, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WGCLTEST));

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int)msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WGCLTEST));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_CREATE:
		{
			// Use my_var in MessageBox (it throws an error: error C2065: 'my_var': undeclared identifier)
			MessageBox(hWnd, (LPCWSTR)my_var, (LPCWSTR)"Hello World! Its 420!", MB_OK);
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

Can anybody: help me, refer me to a link, give me a tip/hint, or something please?

Recommended Answers

All 5 Replies

You can't put it in DLLMain() because just like any other function the object will disappear as soon as DllMain() returns. Instead, the object must be global. Then to make it visible to the application program you have two choices:
1) use __dllspec(__dllexport) tag __declspec( dllexport ) const char my_var[13] = "Hello World!"; or
2) create a *.def file and ass my_var to it

In the application program extern __declspec( dllimport ) const char my_var[13]; More info here.

You can't put it in DLLMain() because just like any other function the object will disappear as soon as DllMain() returns. Instead, the object must be global. Then to make it visible to the application program you have two choices:
1) use __dllspec(__dllexport) tag __declspec( dllexport ) const char my_var[13] = "Hello World!"; or
2) create a *.def file and ass my_var to it

In the application program extern __declspec( dllimport ) const char my_var[13]; More info here.

The exporting works, but I cant import the variable. It says: Unresovled exertnal symbol extern __declspec( dllimort )
I even tried loading user32.lib manually even though it was automatically linked.
And yes, I didnt put the import in WinMain().
Any tips on what I'm doing wrong?

um .. could it be a spelling mistake on your part ?

its __declspec( dllimport )

not __declspec( dllimort )

um .. could it be a spelling mistake on your part ?

its __declspec( dllimport )

not __declspec( dllimort )

No, the keyword highlighted, thats how I know it was not mispelled.
I just mispelled it on the thread, but not in the code.

Did you link your application program with the *.lib file that the compiler produced for the *.dll program?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.