Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа 08 по СиАОД(УТС).doc
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
674.82 Кб
Скачать

Методика выполнения работы Создание статической библиотеки с помощью репозитория объектов

Поместите в папку файлы, прилагаемые к лабораторной работе.

        1. Запустите среду C++ Builder.

        2. Закройте созданную средой форму (File -> Close All);

        3. Выберете пункт New из меню File.

        4. В закладке выберите объект Library

На экране появится окно такое окно:

        1. В главном меню выберете пункт Project -> Add to Project и последовательно откройте модули, которые требуется поместить в библиотечный файл.

        2. Сохраните проект (Save All) под именем, которым вы хотите назвать библиотечный файл.

        3. В главном меню выберете пункт Project -> Make [имя файла библиотеки]

        4. Если ошибок в модулях нет, то на диске будет создан файл с расширением LIB.

        5. Закройте проект.

Использование файла библиотеки модулей

  1. Создайте заготовку для новой программы (New Application) и сохраните ее.

  2. Добавьте библиотеку модулей в проект (Project -> Add to Project).

  1. Напишите обработчик события. Помните о прототипах вызываемых функций.

typedef float ** Matrix_Float;

Matrix_Float Get_mem ( int n, int m );

void Del_mem (Matrix_Float, int n );

void __fastcall TForm1::Panel1Click(TObject *Sender)

{

Matrix_Float Mat = Get_mem ( 10, 10 );

for ( int i =0 ; i < 10; i ++)

for ( int j =0 ; j < 10; j ++)

Mat[i][j] = i*j;

Del_mem ( Mat, 10 );

return;

}

  1. Скомпилируйте программу.

2. Создание динамически подключаемой библиотеки с помощью репозитория объектов

1. Выберете в главном меню пункт File->New. Затем выберете их репозитория объектов объект DLL Wizard.

Будет создан новый пустой проект.

2. Добавьте в заголовок

#include <condefs.h>

  1. Добавьте перед функцией DllEntryPoint()

#define DLLMAINCPP

И вслед за этой строкой

#include “Имя библиотеки.h”

Например,

#include "Own_static_LD.h"

4. Сразу же после функции:

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)

{

return 1;

}

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

// Выделяет память под двумерный массив типа float

// n - число строк

// m - число колонок

float ** _export Get_mem ( int n, int m )

{

float ** buffer; // память для хранения адреса адреса массива,

// в котором будут хранится адреса строк таблицы

// float ** buffer - адрес адреса

buffer = new float *[n]; // запрашиваем память для хранения n

// адресов строк массива

for ( int i =0; i < n ; i ++)

buffer[i] = new float [m]; // выделяем память для

// под строки масива и

// записываем адреса в

// в массив buffer

for ( int i =0; i < n ; i ++)

for ( int j = 0; j < m ; j ++)

buffer[i][j] = 0.0; // в массив записываем нули

return buffer; // возвращаем адреса массива

}

// возвращаем выделенную память OС

void _export Del_mem ( float ** A, int n )

{

for ( int i =0; i < n ; i ++)

delete[] A[i]; // высвобождаем память под строки массива

delete[] A; // высвобождаем память, в которой хранились

// адреса строк

return;

}

# include <math.h>

/ / Определитель матрицы

double _export Det_Matrix ( double **Matrix, int n)

{

double t, d , max, det;

int i, j , k;

d = 1.0;

for ( k = 0; k < n; k ++)

{

max = 0.0;

for (i = k; i < n ; i ++)

{

t = Matrix[i][k];

if ( fabs (t) > fabs (max))

{

max = t; j = i;

}

}

if ( fabs (max) < 0.000001)

{

return 0;

}

if ( j != k)

{

d =- d;

for ( i = k; i < n;i ++)

{

t = Matrix[j][i];

Matrix[j][i] = Matrix[k][i];

Matrix[k][i] = t;

}

}

for ( i = k + 1; i < n; i ++)

{

t = Matrix[i][k] /max;

for ( j = k +1; j < n; j ++)

Matrix[i][j] = Matrix[i][j]- t *Matrix[k][j];

}

d = d* Matrix[k][k];

}

return det;

}

5. Сохраните проект под именем Own_static_LD.cpp

  1. Теперь создаем заголовочный файл для DDL. Выберете в главном меню пункт File->New. Затем выберете объект TEXT.

7. Сохраните файл как Own_static_LD.h. Это имя уже использовалось в директиве (#include "Own_static_LD.h").

Для чего нужен этот файл. Все экспортируемые функции при сборке библиотеки должны иметь спецификатор _export или __declspec(dllexport), а импортируемые _import или __declspec(dllimport). То есть если файл заголовка используется самим DLL, то перед функциями должен стоять один из пары первых спецификаторов, а если использующим DLL приложением, то один из пары вторых.

8. Введите такой код в этот модуль

#if defined(DLLMAINCPP)

# define DLL_SPEC __declspec(dllexport)

#else

# if defined(APPMAINCPP)

# define DLL_SPEC __declspec(dllimport)

# else

# define DLL_SPEC

# endif

#endif

extern "C" float ** DLL_SPEC Get_mem ( int n, int m );

extern "C" void DLL_SPEC Del_mem ( float ** A, int n );

extern "C" double DLL_SPEC Det_Matrix ( double **Matrix, int n);

9. Войдите в пункт меню Project| Make и выполните его. Если ошибок нет, то на диске появятся файлы Own_static_LD.lib и Own_static_LD.dll. Файл Own_static_LD.lib содержит ссылку на библиотеку и список находящихся в ней функций.

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

#define APPMAINCPP

#include "Own_static_LD.h"

#include <vcl.h>

#pragma hdrstop

#include "Main.h"

#define APPMAINCPP

#include "Own_static_LD.h"

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

typedef float ** Matrix_Float;

void Display (Matrix_Float Mat, int n, int m, char *format,TMemo *Memo);

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Matrix_Float Mat = Get_mem ( 10, 10 );

for ( int i =0 ; i < 10; i ++)

for ( int j =0 ; j < 10; j ++)

Mat[i][j] = i*j;

Display (Mat, 10, 10, "%5.1f",Memo1);

Del_mem ( Mat, 10 );

return;

}

Не забудьте подключить lib- файл к проекту (Project | Add to Project).

Динамическая загрузка dll. Динамической загрузкой библиотеки управляется программа.

  1. Вызовете функцию с именем библиотеки:

INSTANCE hDLL = LoadLibrary("Own_static_LD.dll");

Если hDLL!=0, то библиотека загружена в память.

  1. Вызовете функцию для получения адреса функции и библиотеки

My_adr_get = (get_mem)GetProcAddress(hDLL,"_Get_mem");

Обратите внимание, что перед именем функции из dll должен быть символ подчеркивания!

Предварительно требуется описать:

typedef float ** (*get_mem )( int n, int m );

get_mem My_adr_get;

Указатель на функцию, возвращаемый GetProcAddress() должен быть приведен к типу get_mem.

Если My_adr_get!=0, то c функцией можно работать через указатель.

  1. Если библиотеку не планируется использовать, то ее можно выгрузить

FreeLibrary(hDLL);

Пример.

#include <vcl.h>

#include "windows.h"

#pragma hdrstop

#include "Main.h"

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

typedef float ** (*get_mem )( int n, int m );

typedef void (*del_mem )( float ** A, int n );

double Det_Matrix ( double **Matrix, int n);

typedef float ** Matrix_Float;

_fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

void __fastcall TForm1::Button1Click(TObject *Sender)

{

HINSTANCE hDLL;

get_mem My_adr_get;

del_mem My_adr_del;

hDLL = LoadLibrary("Own_static_LD.dll");

if (hDLL == NULL)

{

ShowMessage ("Не могу загрузить DLL "); return;

}

My_adr_get = (get_mem)GetProcAddress(hDLL,"_Get_mem");

if (My_adr_get == NULL)

{

ShowMessage ("Не могу получить адрес Get_mem"); return;

}

My_adr_del = (del_mem )GetProcAddress(hDLL,"_Del_mem");

if (My_adr_del == NULL) {

ShowMessage ("Не могу получить адрес Del_mem"); return;

}

Matrix_Float Mat = (Matrix_Float) My_adr_get( 10, 10 );

for ( int i =0 ; i < 10; i ++)

for ( int j =0 ; j < 10; j ++)

Mat[i][j] = i*j;

My_adr_del ( Mat, 10 );

FreeLibrary(hDLL);

return;

}