DLL в Windows. Создание DLL в Microsoft Visual Studio

dumpbin.exe (в составе Microsoft Использование IDE Microsoft Visual Studio Code) - просмотр DLL, позволяет увидеть список функций, которые есть в DLL.

c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\dumpbin.exe

Файл нужно запускать в Tools→Visual Studio Command Prompt иначе будет ругаться о невозможности найти mspdb100.dll.

my_dll.cpp DLL

// my_dll.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"

#ifdef __cplusplus    // If used by C++ code, 
extern "C" {          // we need to export the C interface
#endif

__declspec(dllexport) TCHAR * __cdecl f1(){
	return L"return Моей DLL 123455";
	}

#ifdef __cplusplus
}
#endif

main_prg.cpp

Исходный код программы подгружающая функцию из DLL.

#include <windows.h>
#include <tchar.h>
#include <string.h>

typedef TCHAR * (__cdecl *func_ptr)();

func_ptr f1;

HWND gr1 = NULL;
HWND ed2 = NULL;

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // прототип функции WndProc

int WINAPI _tWinMain(HINSTANCE hInstance, // дескриптор текущего экземпляра окна
                     HINSTANCE hPrevInstance, // дескриптор предыдущего экземпляра окна
                     LPTSTR    lpCmdLine, // указатель на командную строку
                     int       nCmdShow // показывает состояние окна
) 
{
	MSG uMsg;
	HWND hMainWnd;
	TCHAR szWindowClass[] = L"MyClass"; // имя класса
	WNDCLASSEX wcex; // объявление переменной типа структура оконного класса

	wcex.cbSize = sizeof(WNDCLASSEX); // размер структуры в байтах
	wcex.style			= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;	// стиль-class окна
	wcex.lpfnWndProc	= WndProc; //адрес оконной процедуры (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0; // доп. поля, кот могут потребоваться дальше
	wcex.cbWndExtra		= 0; // доп. поля, кот могут потребоваться дальше
	wcex.hInstance		= hInstance;// описатель приложения, первый параметр функции _tWinMain
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); // определение иконки
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW); // определение курсора LoadCursor(NULL, IDC_CROSS);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1); // установка фона GetSysColorBrush(COLOR_DESKTOP);
	wcex.lpszMenuName	= NULL;		// определение меню
	wcex.lpszClassName	= szWindowClass; // имя класса
	wcex.hIconSm		= NULL; //определение маленькой иконки

		// Регистрируем класс окна 
	if (!RegisterClassEx(&wcex)) { 
		MessageBox(NULL, L"Cannot register class", L"Error", MB_OK); 
		return 0; 
	}

	hMainWnd = CreateWindow(szWindowClass/*имя зарегистрированного или готового класса*/,
	// Создаем основное окно приложения 
		L"A Hellol Application"/*имя окна*/,
		WS_OVERLAPPEDWINDOW/*| WS_VSCROLL*/  /*стили окна*/,
		CW_USEDEFAULT/*расположение окна Х*/,
		0/*расположение окна У*/,
		CW_USEDEFAULT/*ширина окна*/,
		0/*высота окна*/,
		(HWND)NULL/*родитель. если нет, то NULL*/,
		(HMENU)NULL/*дескриптор меню. если меню нет, то NULL. Часто используется как tag*/,
		(HINSTANCE)hInstance/*описатель приложения*/,
		NULL/*исп. в многооконных приложениях. если однооконное, то NULL*/
	);//возвращает описатель окна и передает его в hMainWnd

	// Показываем наше окно 
	ShowWindow(hMainWnd/*описатель окна, кот нужно показать*/, SW_NORMAL/*как именно открыто окно, режимы*/); 
	UpdateWindow(hMainWnd); // Отображение окна

	// Выполняем цикл обработки сообщений до закрытия приложения 
	while (GetMessage(&uMsg/*адрес структуры, принемающей сообщения*/,
		NULL/*из каких окон принемать сообщения. если от всех, то NULL*/,
		0/*ограничение сообщений. если нет, то 0*/,
		0/*ограничение сообщений. если нет, то 0*/
		)/*функция, выбирающая сообщения из очереди cообщений программы*/)
	{ 
	TranslateMessage(&uMsg); /*преобразование нажатия симбольных клавиш (облегчение работы определения нажатой клавиши)*/
	DispatchMessage(&uMsg); //отсылает сообщения в оконную процедуру WndProc
	}

	return 0;
}

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

	switch (uMsg)
	{
	case WM_CREATE:
		{
CreateWindow(L"BUTTON",L"Load DLL",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,306,40,140,40,hWnd,(HMENU)20,GetModuleHandle(NULL),0);
ed2=CreateWindow(L"EDIT",L"Едит 2",WS_CHILD|WS_VISIBLE|WS_BORDER,300,250,250,40,hWnd,(HMENU)12,GetModuleHandle(NULL),0);
		}break;
	case WM_COMMAND:
		{
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		if(wmId == 20)
		{
// Загрузить DLL

HINSTANCE hinstLib;

// Get a handle to the DLL module.

hinstLib = LoadLibrary(TEXT("my_dll.dll"));

if (hinstLib == NULL){

MessageBox(NULL, TEXT("DLL не загружена"), TEXT("DLL не загружена"), MB_OK | MB_ICONINFORMATION);}

if (hinstLib){

	f1=(func_ptr)GetProcAddress(hinstLib,"f1");
}
TCHAR buff[200] = {0};//иначе ругается что передаваемая строка из DLL не заканчивается нулем
wcscat_s(buff,200,f1());
SetWindowText(ed2, buff);
		}
		}break;
	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}
PQ VPS сервера в 28+ странах.