Создадим проект приведенного на скриншоте типа Добавим в проект новый заголовочный файл
Скачать 376.73 Kb.
|
Создадим проект приведенного на скриншоте типа: Добавим в проект новый заголовочный файл: И добавим в этот файл следующий код: В .cpp-файл скопируем файл Utility.cpp из прошлой работы, внеся в него небольшие изменения (подключим созданный выше заголовочный файл, а также добавим область видимости Utility:: перед основными структурами класса). Для экспорта в класса в библиотеку добавим указанный выше флаг препроцессора в настройки проекта: Собираем созданный проект, на выходе получаем DLL-файл в папке debug: Продемонстрируем неявное связывание. Создадим тестовый проект, и подключим к нему всё необходимое. Начнём с заголовочного файла: Подключим .lib-файл: А затем и .dll-файл (последний не забываем поместить его в каталог с приложением!): Изменим .cpp-файл проекта следующим образом, и получим готовый проект: Теперь покажем явное связывание - повторяем предыдущим шаги, и модифицируем главный файл проекта следующим образом: Исходные коды: Для приложения, собирающего DLL: metadataLibrary.cpp //loading data from file, building hierarchy, creating menu strip, etc #include "pch.h" #include #include #include #include #include #include #include "metadataLibrary.h" //constructor with filename as argument Utility::Utility(std::string filename) { parseFile(filename); loadMenu(); } //line from file parsed into separate variables struct Utility::OneRecord { int levelNumber; std::string itemName; int itemStatus; std::string methodName; }record[100]; //loading data from file into struct variables void Utility::parseFile(std::string filename) { std::fstream inputFile; int linesNumber = std::count(std::istreambuf_iterator std::istreambuf_iterator inputFile.open(filename); std::string str; std::getline(inputFile, str);//reading file line by line std::istringstream iss(str); for (int i = 0; i < 100; i++) { inputFile >> record[i].levelNumber >> record[i].itemName >> record[i].itemStatus >> record[i].methodName; } } void Utility::loadMenu() { int currLevel = 0; System::Windows::Forms::Form^ mainWindow = gcnew System::Windows::Forms::Form(); System::Windows::Forms::MenuStrip^ mainMenu = gcnew System::Windows::Forms::MenuStrip(); mainWindow->Controls->Add(mainMenu); //iterating through every record, adding items and sub-items based on hierarchy level for (int i = 0; i < 100; i++) { while (record[i].levelNumber == currLevel) { System::Windows::Forms::ToolStripMenuItem^ menuItem = gcnew System::Windows::Forms::ToolStripMenuItem(record[i].itemName); //setting item status switch (record[i].itemStatus) { case 0: menuItem->Enabled = true; menuItem->Visible = true; break; case 1: menuItem->Enabled = false; break; case 2: menuItem->Visible = false; break; default: break; } //adding sub-item into strip menu according to hierarchy while (record[i].levelNumber != 0 && record[i].levelNumber < currLevel) { System::Windows::Forms::ToolStripMenuItem^ SubStripMenu = gcnew System::Windows::Forms::ToolStripMenuItem(record[i].itemName); menuItem->DropDownItems->Add(SubStripMenu); } //adding item into main strip menu mainMenu->Items->Add(menuItem); currLevel++; } } } metadataLibrary.h // metadataLibrary.h - Contains declarations of Utility class functions #pragma once #include #ifdef UTILITY_EXPORTS #define UTILITY_API __declspec(dllexport) #else #define UTILITY_API __declspec(dllimport) #endif class Utility { public: UTILITY_API Utility(std::string filename); private: UTILITY_API struct OneRecord; UTILITY_API void parseFile(std::string filename); UTILITY_API void loadMenu(); }; Приложение с явным связыванием: using namespace System; using namespace System::Windows::Forms; #include "MainForm.h" #include "metadataLibrary.h" #include #include #include [STAThread] void main(array Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); DLLClient::MainForm form; Application::Run(% form); //DLL loading HINSTANCE hModule = NULL; hModule = ::LoadLibrary(_T("DLL.dll")); //getting a pointer to the constructor void (Utility:: * pConstructor)(std::string); (FARPROC&)pConstructor = GetProcAddress(hModule, "Utility"); //allocating heap memory char* _pc = new char[sizeof(Utility)]; Utility* pc = (Utility*)_pc; //calling a constructor (pc->*pConstructor)("file1.txt"); } Приложение с неявным связыванием: MainForm.cpp using namespace System; using namespace System::Windows::Forms; #include "MainForm.h" #include "metadataLibrary.h" #include #include #include [STAThread] void main(array Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); DLLClient::MainForm form; Application::Run(% form); Utility obj("file1.txt"); } |