Разработка DLL на языке С++, страница 4

¨  В дереве слева найдите и выделите узел Linker4General, а в списке справа найдите строку: Output File. Введите в нее такой путь C:/Debug/$(ProjectName).exe.

¨  Измените главный файл проекта MyDLLCliet.cpp. Нам не нужна точка входа _tmain с параметрами командной строки. Замените ее на обычную функцию main (без параметров).

¨  Как и ранее, откажитесь от Unicode (установите Use Multibyte characters).

¨  Далее, вы изменяете файл stdafx.h, определяющий содержимое PCH. Он должен иметь вид:

#pragma once

#pragma comment(lib, "C:/Debug/MyDLL.lib")

#include <math.h>

#include <iostream>

using namespace std;

Директива #pragma comment(lib, "C:/Debug/MyDLL.lib") является альтернативой установке дополнительных свойств проекта. Вместо этой директивы вы можете установить значение C:/Debug/MyDLL.lib для свойства проекта Additional Dependency. Оно расположено в Property Pages4Linker4Input. Вводимое значение представляет собой путь к файлу описания библиотеки: LIB-файлу, сопровождающему каждую DLL. Файл MyDLL.lib содержит заголовки сущностей, экспортируемых библиотекой MyDLL.dll.

Особенности алгоритма

Развитие программы требует создания функции FillMatrix для ввода коэффициентов расширенной матрицы. Рекомендую сделать это самостоятельно, а здесь, имея в виду учебный и исследовательский характер примера, мы создадим функцию FillMatrix, которая будет генерировать плохо обусловленную матрицу произвольного порядка. Цель — исследовать процесс нарастания вычислительной неустойчивости, довольно часто встречающийся в практике решения реальных систем.

Вектор правых частей (который следует расположить в последнем столбце расширенной матрицы) будем вычислять так, чтобы решение сгенерированной системы было заранее определено и равно, например,

x[0]=1, x[1]=2,..., x[n-1]=n

Итак, мы заранее знаем решение системы, но хотим увидеть как справится с этим наш модуль Gauss. Такой подход позволяет увидеть, как процесс решения плохо обусловленной системы уравнений постепенно (с ростом порядка системы) теряет устойчивость и заранее известное нам решение искажается. Оставляя анализ причин плохой обусловленности предложенной матрицы для курса линейной алгебры, дадим простой алгоритм вычисления коэффициентов матрицы с отмеченным свойством.

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

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

a[i][j] = sin ((i+j+.2) / 20.);

Как показывает тест, процесс решения системы с такой матрицей разваливается уже при n=3, хотя при n=2 решение еще соответствует заданному. Если в выражение для a[i][j] добавить член log(i+j+1.), то свойства системы немного улучшатся. Решение начнет искажаться только при n = 8. При n = 10 максимальная ошибка решения составляет примерно 20%. При n = 11 полученный вектор x[] имеет мало общего с решением. Предлагаем затем исследовать решение, добавляя другие члены к выражению для a[i][j], например: exp((i+j)/3.).

В соответствии с принятым алгоритмом, когда решение выбрано заранее, элементы последнего столбца расширенной матрицы (т.е. вектора правых частей) следует вычислять, как скалярное произведение соответствующей строки матрицы на вектор желаемого решения. Здесь нарастающее во внутреннем цикле значение (j+1) выполняет роль желаемого решения.

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

for (j=0, a[i][n]=0.; j<n; j++)

a[i][n] += a[i][j] * (j+1);

В системе уравнений с выбранной матрицей модификация метода Гаусса (с выбором ведущего или главного элемента) не спасает процесс вычисления от нарастающей неустойчивости.

Реализация клиентского приложения

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

#include "stdafx.h"

//===== Импортируемые сущности

extern __declspec(dllimport) int progress;

extern __declspec(dllimport) char* error;

class __declspec(dllimport) Geometry

{

public:

Geometry();

Geometry (int nx, int ny);