Создание консольного приложения, ссылающегося на динамическую библиотеку




Экспортирование функций из DLL

Чтобы приложение могло обращаться к функциям динамической библиотеки, каждая из них должна занимать строку в таблице экспортируемых функций DLL. Есть два способа занести функцию в эту таблицу на этапе компиляции.

Метод __declspec (dllexport)

Можно экспортировать функцию из DLL, поставив в начале ее описания модификатор __declspec (dllexport).

Второй метод, работает с файлами определения модуля (.def), и позволяет лучше управлять процессом экспортирования.

Файлы определения модуля

Синтаксис файлов с расширением.def в Visual C++ достаточно прямолинеен, главным образом потому, что сложные параметры, использовавшиеся в ранних версиях Windows, в Win32 более не применяются. Как станет ясно из следующего простого примера,.def-файл содержит имя и описание библиотеки, а также список экспортируемых функций:

MyDLL.def
LIBRARY "MyDLL"
DESCRIPTION 'MyDLL - пример DLL-библиотеки'
EXPORTS MyFunction @1

В строке экспорта функции можно указать ее порядковый номер, поставив перед ним символ @. Этот номер будет затем использоваться при обращении к GetProcAddress (). На самом деле компилятор присваивает порядковые номера всем экспортируемым объектам. Однако способ, которым он это делает, отчасти непредсказуем, если не присвоить эти номера явно. В строке экспорта можно использовать параметр NONAME. Он запрещает компилятору включать имя функции в таблицу экспортирования DLL:

MyFunction @1 NONAME

Иногда это позволяет сэкономить много места в файле DLL. Приложения, использующие библитеку импортирования для неявного подключения DLL, не "заметят" разницы, поскоьку при неявном подключении порядковые номера используются автоматически. Приложениям, загружающим библиотеки DLL динамически, потребуется передавать в GetProcAddress порядковый номер, а не имя функции.

Создание проекта динамической библиотеки

· В меню Файл выберите пункт Создать, а затем пункт Проект.

· В узле Visual C++ выберите Win32 Console Application.

· Выберите имя для проекта, например DlllLib, и введите его в поле Имя. Выберите имя для решения, например DllLibrary, и введите его в поле Имя решения.

· Для запуска мастера приложений Win32 нажмите кнопку ОК. На странице Общие сведения диалогового окна Мастер приложений Win32 нажмите кнопку Далее(Next)

· На странице Параметры(Application Settings) приложения диалогового окна Мастер приложений Win32 в поле Тип (Application type) приложения выберите пункт Динамическая библиотека(DLL).

· На странице Параметры(Application Settings) приложения диалогового окна Мастер приложений Win32 в поле Дополнительные параметры(Additional options) установите флажок пустой проект (Empty project).

· Чтобы создать проект, нажмите кнопку Готово(Finish).

Вариант без использования классов:

// mydll.h

__declspec(dllexport) void Msg (char* msgstr);

 

// mydll.cpp

#include "Windows.h"
#include <stdexcept>
#include "mydll.h"

using namespace std;


void Msg(char* msgstr)
{
MessageBox(NULL, msgstr, "Message from DLL", MB_OK);
}

Скомпилируйте библиотеку, выбрав команду Построить решение (Build Solution) в меню Построение(Build).

: error C2664: 'MessageBoxW': cannot convert parameter 2 from 'char *' to 'LPCWSTR'

Исправить установив Character Set

В результате будет создана динамическая библиотека, которая может использоваться другими программами (..\dynamicLibrary\Debug\dlllib.lib и..\dynamicLibrary\Debug\dlllib.dll).

Создание консольного приложения, ссылающегося на динамическую библиотеку

· В меню Файл выберите пункт Создать, а затем пункт Проект.

· В узле Visual C++ выберите Win32 Console Application.

· Выберите имя для проекта, например Calldll, и введите его в поле Имя.

· Для запуска мастера приложений Win32 нажмите кнопку ОК. На странице Общие сведения диалогового окна Мастер приложений Win32 нажмите кнопку Далее(Next)

· На странице Параметры(Application Settings) приложения диалогового окна Мастер приложений Win32 в поле Тип (Application type) приложения выберите пункт Консольное приложение(Console application)

· На странице Параметры(Application Settings) приложения диалогового окна Мастер приложений Win32 в поле Дополнительные параметры(Additional options) выберите пункт (Empty project).

· Чтобы создать проект, нажмите кнопку Готово(Finish).

Добавьте файл программы primer.cpp(Add/New item …/C++ file)

#include "mydll.h"

 

 

int main(int argc, char* argv[])

{

 

Msg("Hello, world!");

return 0;

}

Для использования библиотеки необходимо сослаться на эту библиотеку.

Для этого в меню Проект выберите пункт Свойства проекта(Project/CallDll Properties …).

Для создания ссылки на динамическую библиотеку

1. Разверните узел Linker/Input и выберите команду дополнительные ссылки(Additional Dependencies), выберите пустую строку, и нажмите кнопку с многоточием (…) в конце строки. В окне введите имя библиотеки dlllib.lib и нажмите ОК.

2. Разверните узел Linker/General и выберите команду дополнительные каталоги для библиотек (Additional Library Directories), выберите пустую строку, и нажмите кнопку с многоточием (…) в конце строки. В диалоговом окне Выбор каталога нажмите кнопку Выбор папки и выберите каталог, где располагается файл библиотеки dlllib.lib.

В диалоговом окне Дополнительные каталоги включаемых файлов нажмите кнопку ОК чтобы сохранить выбранные значения и закрыть диалоговое окно.

Для создания ссылки на заголовочный файл

Разверните узел С/С++ /General и выберите команду Дополнительные каталоги включаемых файлов (Additional Include Directories), выберите пустую строку, и нажмите кнопку с многоточием (…) в конце строки. В диалоговом окне Выбор каталога нажмите кнопку Выбор папки и выберите каталог, где располагается файл mydll.h. В диалоговом окне Дополнительные каталоги включаемых файлов нажмите кнопку ОК чтобы сохранить выбранные значения и закрыть диалоговое окно.

Постройте исполняемый файл, выбрав команду Построить решение в меню Построение.

Запуск приложения

Ошибка ­– Не найдена библиотека dlllib.dll

Исправить – скопировать файл dlllib.dll в папку Debug(туда где находится исполнимый файл.exe)

Вариант с классом проект DLLCLASS

(должны совпадать имя проекта и #ifdef DLLCLASS_EXPORTS)

TRational.h

#ifndef _DROB_H

#define _DROB_H

#ifdef DLLCLASS_EXPORTS

#define DLL_EI __declspec(dllexport)

#else

#define DLL_EI __declspec(dllimport)

#endif

 

 

#include <string>

using namespace std;

class DLL_EI TRational{

long chis,zn;

void Reduce();

int NOD(long x, long y);

public:

TRational(const long &c=0, const long &z=1);

TRational(const int &c, const int &z);

TRational(const double &r);

string toString();

TRational Add(const TRational &r);

TRational operator +(const TRational &r);

TRational operator +(const long &r);

TRational& operator +=(const TRational &r);

DLL_EI friend ostream& operator >>(ostream &t, const TRational &r);

 

};

#endif

TRational.cpp

#include "TRational.h"

#include <iostream>

#include <string>

#include <sstream>

 

using namespace std;

 

int TRational::NOD(long x, long y){

if(y==0)return x;else return NOD(y, x%y);

}

void TRational::Reduce(){

long t;

t = NOD (chis,zn);

chis /= t;

zn /= t;

}

 

TRational::TRational(const long &c,const long &z):chis(c),zn(z){

 

if (zn==0) {cout<<"Error - divide by zero"; exit;}

Reduce();

}

TRational::TRational(const int &c, const int &z):chis(c),zn(z){

if(zn==0){cout<<"Error - divide by zero"; exit;}

Reduce();

}

TRational::TRational(const double &r){

double val1, val2;

val1 = r*10000000L; val2 =r* 1000000L;

chis = long(val1 -val2);

zn = 90000000L;

Reduce();

}

string TRational::toString(){

stringstream ss (stringstream::in | stringstream::out);

string str;

ss << chis<<'/'<<zn;

ss >> str;

return str;

}

TRational TRational::Add(const TRational &r){

TRational t =*this;

t.zn *=r.zn;

t.chis = t.chis * r.zn + r.chis * t.zn;

t.Reduce();

return t;

}

TRational TRational::operator +(const TRational &r)

{

TRational t =*this;

t.zn *=r.zn;

t.chis = t.chis * r.zn + r.chis * t.zn;

t.Reduce();

return t;

}

TRational& TRational::operator +=(const TRational &r){

 

chis = chis * r.zn + r.chis * zn;

zn *=r.zn;

Reduce();

return *this;

}

TRational TRational::operator +(const long &r){

TRational t(r);

t += *this;

t.Reduce();

return t;

}

 

 

#include <iostream>

#include "TRational.h"

using namespace std;

int main(){

TRational t(5,10),p(10,5);

cout<<t.toString()<<endl<<p.toString()<<endl;

TRational t1;

t1 = t.Add(p);

cout<<t1.toString()<<endl;

t1 = t + p;

cout<<t1.toString()<<endl;

t1 += p += t;

cout<<t1.toString()<<endl;

cout<<p.toString()<<endl;

p = p + 5;

cout<<p.toString()<<endl;

//p = 5 + p;

//cout<<p.toString()<<endl;

system("pause");

 

return 0;

}



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-08-08 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: