Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Повторная загрузка изображения на форму, которая в 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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.052 c
6-1266238609
zensan
2010-02-15 15:56
2013.03.22
TWebBrowser with FTP site


15-1353054590
TStas
2012-11-16 12:29
2013.03.22
КАк устроена флешка? Из любопытства


15-1346597310
Разведка
2012-09-02 18:48
2013.03.22
Посоветуйте книгу


15-1331152205
Юрий
2012-03-08 00:30
2013.03.22
С днем рождения ! 8 марта 2012 четверг


15-1343334602
Юрий
2012-07-27 00:30
2013.03.22
С днем рождения ! 27 июля 2012 пятница