Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизПовторная загрузка изображения на форму, которая в DLL Найти похожие ветки
← →
>|< (2012-07-02 17:37) [0]Здравствуйте, уважаемые мастера!
Есть форма, которая находится в DLL.
На форме находится компонент TImage.
DLL экспортирует функцию, которая для своей работы создает экземпляр формы и загружает в компонент TImage изображение.
При повторном вызове метода Image.LoadFromFile вылетает Access Violation и приложение, которое использует данную DLL падает.
Подскажите, как можно решить данную проблему.
Модуль ShareMem в секции uses подключен.
Заранее благодарен.
← →
>|< (2012-07-02 17:48) [1]Форма создается только один раз при загрузке dll и освобождается только когда приложение завершает свою работу
← →
KilkennyCat © (2012-07-02 18:15) [2]> Image.LoadFromFile вылетает Access Violation
точно там вылетает?
← →
>|< (2012-07-02 18:24) [3]точно
под отладчиком смотрел.
вываливается ---------------------------
Debugger Fault Notification
---------------------------
Project1.exe faulted with message: "access violation at 0x0052658d: write of address 0x00030d6c". Process Stopped. Use Step or Run to continue.
---------------------------
OK
---------------------------
← →
>|< (2012-07-02 18:29) [4]На всякий случай покажу код:
library MRZRecognizer;
uses
ShareMem,
SysUtils,
Classes,
Graphics,
FannNetwork,
Windows,
Dialogs,
MRZ_Recognize in "MRZ_Recognize.pas" {MRZRecognizeForm};
// interface
{$R *.res}
function RecognizeMRZ(AImageFilename: TFilename): widestring;
var trust:TSingle_Array;
begin
if not Assigned(MRZRecognizeForm) then
MRZRecognizeForm := TMRZRecognizeForm.Create(nil);
try
MRZRecognizeForm.Visible := false;
Result := MRZRecognizeForm.RecognizeImage(AImageFilename,trust);
finally
end;
end;
function RecognizeDetails(AImageFilename: string; var values: TInteger_Array;
var trust:TSingle_Array): integer;
var
I: Integer;
RecognisedStr:widestring;
begin
if not Assigned(MRZRecognizeForm) then
MRZRecognizeForm := TMRZRecognizeForm.Create(nil);
try
MRZRecognizeForm.Visible := false;
RecognisedStr := MRZRecognizeForm.RecognizeImage(AImageFilename, trust);
Result := Length(RecognisedStr);
SetLength(values, Result);
for I := 1 to Result do
values[i-1]:=Pos(RecognisedStr[i],MRZ_Chars)-1;
except
on E:Exception do
begin
ShowMessage(E.Message);
Result := -1;
end;
end;
end;
exports RecognizeMRZ, RecognizeDetails;
procedure MyDLLMain(dwReasson: DWORD);
begin
case dwReasson of
DLL_PROCESS_DETACH:
begin
if Assigned(MRZRecognizeForm) then
begin
MRZRecognizeForm.Free;
MRZRecognizeForm := nil;
end;
end;
end;
end;
begin
DllProc := @MyDLLMain;
end.
unit MRZ_Recognize;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, FannNetwork,
DBClient, ComCtrls, acPNG;
const
CharWidth = 11;
CharHeight = 34;
MRZ_Chars = "0123456789<ABCDEFGHIJKLMNOPQRSTUVWXYZ";
type
tsingle_array = array of single;
TInteger_Array = array of integer;
TMRZRecognizeForm = class(TForm)
...
...
...
function TMRZRecognizeForm.RecognizeImage(Afilename: string;
var trust:TSingle_Array): widestring;
var
BMP1: TBitmap;
begin
Result := "";
Image1.Picture.LoadFromFile(Afilename);
//в этом месте при второй попытке вылетает Access Violation
BMP1 := TBitmap.Create;
try
BMP1.Height := Image1.Height + 10;
BMP1.Width := Image1.Width + 10;
BMP1.Canvas.Draw(5, 5, Image1.Picture.Graphic);
Image1.Picture.Bitmap.Assign(BMP1);
finally
BMP1.Free;
end;
Result := GetImageChars(Image1.Picture.Bitmap, trust);
end;
end.
← →
Anatoly Podgoretsky © (2012-07-02 18:54) [5]
> Модуль ShareMem в секции uses подключен.
Это только слова, а вот что в файле проекта?
← →
>|< (2012-07-02 19:02) [6]в окне CPU под отладчиком вываливается в методе
LoadResString:
на строчке
0052658D 6800040000 push $00000400
если эта информация сможет помочь найти причину проблемы...
Туманно я догадываюсь, что из-за того что форма в в dll, ресурсы связанные с ней нужно как-то расшарить для повторного доступа к ним.
Но пока понятия не имею, как это сделать.
ShareMem использовал, но он ничего не дал.
Даже пересоздаю каждый раз форму при вызове функции - и это не помогло.
Ошибка осталась та же.
← →
>|< (2012-07-02 19:03) [7]
> Это только слова, а вот что в файле проекта?
код приведен в посте >|< (02.07.12 18:29) [4]
← →
>|< (2012-07-02 19:12) [8]когда добавил пересоздание формы для каждого вызова экспортируемой функции, то AV начал выпадать в месте второго создания формы:
function RecognizeDetails(AImageFilename: string; var values: TInteger_Array;
var trust: TSingle_Array): integer;
var
I: Integer;
RecognisedStr: widestring;
begin
// if not Assigned(MRZRecognizeForm) then
MRZRecognizeForm := TMRZRecognizeForm.Create(nil); <- при втором вызове здесь вываливает Access Violation
try
try
MRZRecognizeForm.Visible := false;
RecognisedStr := MRZRecognizeForm.RecognizeImage(AImageFilename, trust);
Result := Length(RecognisedStr);
SetLength(values, Result);
for I := 1 to Result do
values[i - 1] := Pos(RecognisedStr[i], MRZ_Chars) - 1;
except
on E: Exception do
begin
ShowMessage(E.Message);
Result := -1;
end;
end;
finally
FreeAndNil(MRZRecognizeForm);
end;
end;
← →
>|< (2012-07-02 19:42) [9]Нашел в чем причина.
Модуль ShareMem нужно подключать не только в library но и в приложении, которое использует эту Dll.
Но возникла другая проблема:
При закрытии приложения появляется такая ошибка:
---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EInvalidPointer with message "Invalid pointer operation". Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
← →
Anatoly Podgoretsky © (2012-07-02 20:00) [10]Как видишь в [4] ничего не приведено и у тебя еще куча ошибок и связаны они все с неправильным использованием ДЛЛ, необходимость которой под вопросом.
← →
>|< (2012-07-02 20:12) [11]
> необходимость которой под вопросом
в этом как раз вопросов нет. заказчик загадал сделать в виде dll, чтобы использовать из Java.
> и у тебя еще куча ошибок и связаны они все с неправильным
> использованием ДЛЛ
можно с этого места поподробней?
Буду очень признателен.)
Или хотя бы ссыль бросьте, где можно почитать, как правильно работать с DLL
← →
KilkennyCat © (2012-07-02 21:15) [12]
> MRZRecognizeForm := TMRZRecognizeForm.Create(nil);
а nil ли здесь должен быть?
← →
Давайте будем жрать! (2012-07-02 21:51) [13]
> а nil ли здесь должен быть?
Вай нот? Он же сам её разрушает.
← →
KilkennyCat © (2012-07-02 22:10) [14]а мне казалось, что нужно на вызвавшее ссылаться....
← →
Ega23 © (2012-07-02 23:47) [15]
> в этом как раз вопросов нет. заказчик загадал сделать в
> виде dll, чтобы использовать из Java.
И ты думаешь, что в Java есть свой ShareMem?
← →
Leonid Troyanovsky © (2012-07-02 23:58) [16]
> >|< (02.07.12 20:12) [11]
> Или хотя бы ссыль бросьте, где можно почитать, как правильно
> работать с DLL
http://msdn.microsoft.com/en-us/windows/hardware/gg487379.aspx
--
Regards, LVT.
← →
KilkennyCat © (2012-07-03 00:04) [17]
> И ты думаешь, что в Java есть свой ShareMem?
вот тож об этом подумал...
← →
Германн © (2012-07-03 01:28) [18]
> Ega23 © (02.07.12 23:47) [15]
>
>
> > в этом как раз вопросов нет. заказчик загадал сделать
> в
> > виде dll, чтобы использовать из Java.
>
>
> И ты думаешь, что в Java есть свой ShareMem?
Правильнее было бы спросить думает ли автор, что в Java есть дельфийский ShareMem? И не только в Java, но и во всех языках, кроме самой Дельфи.
← →
AV © (2012-07-03 09:32) [19]а где передача глобальных переменных forms
application, Screen и что там еще
← →
AV © (2012-07-03 09:34) [20]и да, если dll пишется для другого языка - только pchar допустим
← →
Anatoly Podgoretsky © (2012-07-03 09:37) [21]Не надо писать ДЛЛ если не в ладах с ними, будет очень больно.
← →
AV © (2012-07-03 09:42) [22]http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=512
начать отсюда
и все related ссылки
а правильный ответ -
> Не надо писать ДЛЛ если не в ладах с ними, будет очень больно.
:)
← →
AV © (2012-07-03 09:59) [23]полгода дописывал мега-прогу на dll.. что ни форточка, то dll
истинной независимости при мне добиться не удалось(потом ушел), а гемора - сколько хочешь было..
Вроде все работает - положили новый компонент на формочку - опять побочный косяк. (компанент к какому нибудь глобальному объекту обращается, которого еще не передавали. Находим в дебаге какого и добавляем передачу и его.. )
В конце простая форма, без всего, уже ловит over 9000 передач всякой фигни..
Проще(в over 9000 раз) все в одном exe делать.
dll для другого языка - не знаю..
Я бы если только не визуальную работу вынес. А казать - пусть та апликуха сама кажет.
← →
>|< (2012-07-03 11:40) [24]
> Не надо писать ДЛЛ если не в ладах с ними, будет очень больно.
Я и не писал до этого, пока не возникла такая необходимость.
Почему бы сейчас не разобраться с этим?
Зачем всю жизнь страдать и приносить страдания другим своими кривыми DLL-ками?))) Намного лучше будет научиться писать хорошие DLL-ки.
Надеюсь, Мастера мне в этом помогут.)) Ну хотя бы тонкими намеками))))
Тем более, что заказчику понравилась моя программа распознавания текста, построенная на базе нейронной сети, которая распознает не хуже FineReader)))
От того и форма оказалась в DLL-ке.
Думал, как проще переделать приложение в DLL-ку, но наткнулся на такие грабли...
Итог такой: ShareMem выбрасываем.
Соответственно из DLL выбрасываем Forms, String, WideString.
Соответственно экспорт будет сводиться к такой функции:
type
TSingleArray = array of single;
TIntegerArray = array of integer;
function RecognizeImage(Afilename: PChar;
out trust:TSingleArray; out char_codes:TIntegerArray): HResult;stddecl;
Теперь такой вопрос: сможет ли java-программист достать из массивов trust и char_codes значения этих массивов? или нужно для него выбрать другой тим исходящих переменных?
← →
>|< (2012-07-03 11:41) [25]
> >|< (02.07.12 19:42) [9]
>
> Нашел в чем причина.
> Модуль ShareMem нужно подключать не только в library но
> и в приложении, которое использует эту Dll.
>
> Но возникла другая проблема:
> При закрытии приложения появляется такая ошибка:
> ---------------------------
> Debugger Exception Notification
> ---------------------------
> Project Project1.exe raised exception class EInvalidPointer
> with message "Invalid pointer operation". Process stopped.
> Use Step or Run to continue.
> ---------------------------
> OK Help
> ---------------------------
с этим тоже разобрался, когда указал в правильном месте ShareMem:-)
← →
>|< (2012-07-03 11:48) [26]
> полгода дописывал мега-прогу на dll.. что ни форточка, то
> dll
> истинной независимости при мне добиться не удалось(потом
> ушел), а гемора - сколько хочешь было..
> Вроде все работает - положили новый компонент на формочку
> - опять побочный косяк. (компанент к какому нибудь глобальному
> объекту обращается, которого еще не передавали. Находим
> в дебаге какого и добавляем передачу и его.. )
> В конце простая форма, без всего, уже ловит over 9000 передач
> всякой фигни..
> Проще(в over 9000 раз) все в одном exe делать.
Я через это проходил. Но формы делал в bpl.
Получилось очень удобно. Если в приложении 100 форм и нужно добавить 101 форму, то достаточно создать bpl-ку с необходимой дочерней формой, подвязать ее через базу в дерево форм, и вуаля - загрузка, обновления, раздача прав доступов - на нее распространяется все, если наследовать ее от правильного предка.
← →
brother © (2012-07-03 11:53) [27]Хочу узнать у автора топика, а никнейм у Вас это попа?
← →
>|< (2012-07-03 11:54) [28]
> Хочу узнать у автора топика, а никнейм у Вас это попа?
кому чего не хватает, тот то и видет)))
← →
>|< (2012-07-03 14:05) [29]Все разрешилось как нельзя лучше.))
Уже никакой DLL не нужно.
Я передал исходники Delphi-проекта и их переписали под .Net и внедрили в свое приложение.
Всем спасибо за участие!
Особенно Leonid Troyanovsky © (02.07.12 23:58) [16] за полезную доку!
И Анатолию Подгорецкому, который увидел суть проблемы невооруженным взлядом и не указал прямо на причину, а заставил найти самому.
Поступил как настоящий дзен-буддист: если у тебя просят рыбу - дай человеку удочку, пусть научится и словит)))
← →
icWasya © (2012-07-03 14:11) [30]На будущее - WideString можно оставить - это стандартный системный тип.
А вот это
TSingleArray = array of single;
TIntegerArray = array of integer;
это уже Борландовские примочки, и в других языках работать не будут.
← →
>|< (2012-07-03 14:14) [31]
>
> А вот это
> TSingleArray = array of single;
> TIntegerArray = array of integer;
> это уже Борландовские примочки, и в других языках работать
> не будут.
На будущее: чем это можно заменить?
← →
Anatoly Podgoretsky © (2012-07-03 14:19) [32]
> На будущее - WideString можно оставить - это стандартный
> системный тип.
Дело не в стандартности, а в том что это не ссылочный тип, обычный PChar, только для юникода
← →
Anatoly Podgoretsky © (2012-07-03 14:19) [33]
> На будущее: чем это можно заменить?
Статическими массивами
← →
AV © (2012-07-03 14:37) [34]
> Я через это проходил. Но формы делал в bpl.
Тут мне тоже самое тогда говорили, но меня не послушали.
И потом так и стали делать, уже без меня, насколько мне известно. :)
Про dll тогда усвоил одно -
1. только простые типы.
2. только закулисная работа
Остальное можно, но муторно. Гораздо проще и надежнее перекомпилировать другую версию с другими модулями.
← →
icWasya © (2012-07-04 10:07) [35]Anatoly Podgoretsky © (03.07.12 14:19) [32]
>>> На будущее - WideString можно оставить - это стандартный
>>> системный тип.
>Дело не в стандартности, а в том что это не ссылочный тип, обычный PChar, только для юникода
Не только. В Windows есть специальное API для работы с такими строками. И поскольку создание/уничтожение делается средствами Windows, то такие строки можно передавать между модулями, и, в том числе, создавать в одном месте, а уничтожать в другом.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.076 c