Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.082 c
15-1342187339
SeaData
2012-07-13 17:48
2013.03.22
[работа] Требуется старший программист (Delphi + MySQL)


15-1337202631
Германн
2012-05-17 01:10
2013.03.22
Подскажите инструмент


1-1298637110
evgeso
2011-02-25 15:31
2013.03.22
После закрытия Ошибка Invalid Pointer Operation


15-1330664086
CleriC
2012-03-02 08:54
2013.03.22
HotKey в среде Delphi (не могу назначить)


15-1340051402
Юрий
2012-06-19 00:30
2013.03.22
С днем рождения ! 19 июня 2012 вторник





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский