![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ошибка в DLL? [D5]
Sour © (2002-02-18 09:12:00)Имеется:
1. библиотека(DLL):
library Project2;
uses
SysUtils,
Classes;
type
TMy = record
N: integer;
A: array of integer;
end;
function Get: TMy;
var
Tmp: TMy;
i: integer;
begin
SetLength(Tmp.A, 100);
Tmp.N := -12;
for i := Low(Tmp.A) to High(Tmp.A) do
Tmp.A[i] := Random(100);
Result := Tmp;
end;
exports
Get;
begin
end.
2. Проект
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TMy = record
N: integer;
A: array of integer;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
Tmp: TMY;
public
{ Public declarations }
end;
function Get: TMy; external "project2.dll"
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);//Событие на нажатие Button1
begin
Tmp := Get;
end;
end.
Если нажать на кнопку Button1, а потом закрыть программу, то выдается сообщение об ошибке
Invalid pointer operation. Что я сделал не так?
Набережных С. (2002-02-26 14:41:00) [1]
> Aleks1 (26.02.02 01:10)
В конструкцииResult := Tmp;происходит присваивание значений полей рекорда Tmp полям рекорда Result. То же происходит приTmp := Get;. Но одно из полей содержит ссылку на область памяти. У DLL и EXE разные менеджеры памяти, ничего не знающие друг о друге - в этом и проблема. Полагаю, это и имел в виду Digitman ©. ShareMem заменяет эти менеджеры собственным, и именно поэтому она должна идти первой в файле проекта(dpr), иначе будут задействованы внутренние менеджеры. Остальные модули проекта не имеют значения. Но, на мой взгляд, лучше вообще забыть о ShareMem и действовать стандартно, самостоятельно выделяя и освобождая память в одном месте(лучше - в EXE).
Aleks1 (2002-02-26 01:10:00) [2]Блин, хлопцы, почему вы все проигнорировали замечание:
Digitman © (22.02.02 10:07)
Он ведь указал на конкретную ОШИБКУв приведенном коде?
Результат функции Get присваивается локальной переменной Tmp, которая после выхода из функции теряет смысл!
Набережных С. (2002-02-25 22:33:00) [3]Покажи код.
Набережных С. (2002-02-25 22:30:00) [4]В файлах с расширением .dpr? Тогда ошибка не в приведенном коде.
Sour (2002-02-25 21:51:00) [5]ShareMem в файлах первый!!!!
Набережных С. (2002-02-24 22:00:00) [6]ShareMem нужно ставить первым в файлы проекта DLL и EXE.
Sour (2002-02-24 21:20:00) [7]Ребята, рассуждения на тему где что очищается верны! Т.е. у меня возникло предположение, что динамический массив очищается дважды. Но как этого избежать? Вопрос остается открытым.
Digitman (2002-02-22 10:07:00) [8]что, по-твоему, происходит в строчке
Result := Tmp;
где Tmp - локальная переменная ?
MBo (2002-02-22 08:20:00) [9]видимо, потому что создаешь дин. массив в одном месте, а при выходе он уничтожается в другом.
Sour (2002-02-21 20:13:00) [10]Даже если ShareMem в начале uses всех модулей поставить и в рабочий каталог boralndmm.dll кинуть, что на завершение работы программы возникает ошибка Invalid Pointer Operation!!!!
MBo (2002-02-18 09:28:00) [11]динамический массив -> uses sharemem первым надо писать