Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.06.02;
Скачать: [xml.tar.bz2];

Вниз

DLL   Найти похожие ветки 

 
_Narayan_   (2003-05-17 22:25) [0]

Надеюсь найдутся добрые люди, оч помощь нужна.

Проблема такая. В процедуре(1) загружаю DLL явным образом.
... LoadLibrary ... GetProcAddress ...
... использую_процедуру ...
... FreeLibrary ...
При завершении процедуры(1) (т.е. при выходе из неё)
наблюдаю ошибку Access Violation.


 
Palladin   (2003-05-17 22:54) [1]

код где? кто тебе скажет, или предлагаешь перечислять все варианты ошибок? может быть все что угодно


 
_Narayan_   (2003-05-17 23:02) [2]

ОК, вот он
(замечу, ошибка возникает не в где-то, а именно при выходе из это процедуры, т.е. добавляю в конце пару операторов - они отрабатывают нормально, вот )


procedure TFormMain.mFillReportList;
var FData: TSearchRec;
i: Integer;
ReportInfo: TReportInfoRec;
LibHandle: THandle;
mGetDLLHeader: TmGetDLLHeader;
// mDoReport: TmDoReport;
begin
ComboBox1.Clear;
SetLength(ActiveReports,0);
i:=0;
If FindFirst((BDInfo.PathToReports+"*.dll"),faAnyFile,FData)=0 then
Repeat
If not IsDotOrTwoDot(FData.Name) Then If FData.Size>0 Then
Begin
LibHandle:=LoadLibrary(pChar(BDInfo.PathToReports+FData.Name));
Try
If LibHandle=0 Then Raise EDLLLoadError.Create("Не удаётся подключить библиотеку"+BDInfo.PathToReports+FData.Name);
@mGetDLLHeader:=GetProcAddress(LibHandle,"mGetDLLHeader");
If (@mGetDLLHeader=nil) Then RaiseLastWin32Error Else
Begin
mGetDLLHeader(@ReportInfo);
inc(i);
SetLength(ActiveReports,i);
ActiveReports[i-1].mIndex:=ComboBox1.Items.Add(ReportInfo.WhatFor);
ActiveReports[i-1].mFileName:=BDInfo.PathToReports+FData.Name;
end;
Finally
FreeLibrary(LibHandle);
end;
end;
Until FindNext(FData)<>0;

SysUtils.FindClose(FData);
end;


 
_Narayan_   (2003-05-18 00:17) [3]

Вот, здесь тоже самое, тока поцедура попроще


procedure TFormMain.BitBtn1Click(Sender: TObject);
var LibHandle: THandle;
mDoReport: TmDoReport;
begin
LibHandle:=LoadLibrary(pChar(ActiveReports[ComboBox1.ItemIndex].mFileName));
Try
If LibHandle=0 Then Raise EDLLLoadError.Create("Не удаётся подключить библиотеку"+ActiveReports[ComboBox1.ItemIndex].mFileName);
@mDoReport:=GetProcAddress(LibHandle,"mDoReport");
If (@mDoReport=nil) Then RaiseLastWin32Error Else
Begin
mDoReport(PChar(BDInfo.ServerName+":"+BDInfo.FileName),@SelectedPers);
end;
Finally
FreeLibrary(LibHandle);
end;
end;


 
Palladin   (2003-05-18 00:19) [4]

нужно объявление типа процедуры и описание процедуры в dll, надеюсь соглашение о вызовах совпадает...
а так другого повода для ошибки не вижу...


 
Johnmen   (2003-05-18 00:28) [5]

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


 
_Narayan_   (2003-05-18 00:50) [6]

Обьявлени такое
(описание в длл тожа имеется ;-) )


Type TmGetDLLHeader = procedure (ReportInfo: PReportInfoRec); stdcall;
Type TmDoReport = procedure (DBNamePath: PChar; SelectedPers: PSelectedPersRec); stdcall;


а других соглашений о вызовах я в глаза не видел


 
_Narayan_   (2003-05-18 00:53) [7]

2 Johnmen

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


 
Johnmen   (2003-05-18 01:33) [8]

>_Narayan_ (18.05.03 00:53)

Хотя бы здесь :

inc(i);
SetLength(ActiveReports,i);
ActiveReports[i-1].mIndex:=ComboBox1.Items.Add(ReportInfo.WhatFor);

Как можно содержательно обращаться к элементу строки 0 (ноль) ???????
:)))


 
_Narayan_   (2003-05-18 09:12) [9]

2 Johnmen
Да уж...
Это не строка, а динамический массив ...

Может у кого-нить ещё есть варианты



 
Malder   (2003-05-18 12:24) [10]

Что такое ActiveReports ?


 
_Narayan_   (2003-05-18 22:05) [11]

2 Malder
...
type PSelectedPersRec = ^TSelectedPersRec;
TSelectedPersRec = record
PersLUIDs: array of Integer;
end;
...
var
ActiveReports: array of TRepRec;
...


 
Malder   (2003-05-18 23:14) [12]

1) Ну а что такое TRepRec ? Зачем ты привел описание какого-то TSelectedPersRec ?

2) ActiveReports - глобальная переменная ?

3) что такое TReportInfoRec


 
_Narayan_   (2003-05-18 23:23) [13]

простите, сэр
вот...

type
PRepRec = ^TRepRec;
TRepRec = record
mIndex: Integer;
mFileName: String;
end;
...
var
ActiveReports: array of TRepRec;
...


 
nikkie   (2003-05-19 09:05) [14]

читал такое?
{ Important note about DLL memory management: ShareMem must be the
first unit in your library"s USES clause AND your project"s (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }


 
Palladin   (2003-05-19 09:16) [15]

как всегда, вытянув из больного клещами симптомы (ну как будто не надо ему это) приходим к выводу, что руки не мыли... от того и...


 
danja   (2003-05-19 11:17) [16]

Простите, что вмешиваюсь, но туп донельзя, и поэтому про симптомы еще куда ни шло, а вот с лекарством так и не разобрался. Несмотря на то что про ShareMem читал в коментарии и даже в uses вставил - не помогло : следующий параметр после строки передается неверно, та же самая ерунда с передачей потока :

procedure VLImport(const FileName : String; OCnt : Integer;
LMSZ : TMemoryStream; var Lim : TRect; );

Параметры OCnt и Lim передаются неверно. Плюс : ошибка при выходе, но уже не из вызывающей процедуры, а из программы.
Хотя все вроде бы делаю по книжке (Тейксейра с Пачекой) и по примерам - толку добиться не могу. Помогите, кому не жалко.


 
Skier   (2003-05-19 11:29) [17]

>danja (19.05.03 11:17)
ShareMem надо ставить первым в списке под-ых модулей и в
DLL и в host-приложении


 
danja   (2003-05-19 11:44) [18]

> Skier (19.05.03 11:29)
Спасибо на добром слове, но не помогло.
Вставил в вызывающий модуль, а затем и в модуль главной формы - ничего не изменилось?


 
nikkie   (2003-05-19 11:47) [19]

осталось вставить в dpr...


 
Skier   (2003-05-19 11:48) [20]

судя по всему, проблема в LMSZ : TMemoryStream.
Пакет должен помочь...


 
danja   (2003-05-19 11:57) [21]

Я не гордый, я могу и в dpr, и потоки убрал, а таже самая фигня:
после строки параметры передаются неверные!


 
evvcom   (2003-05-19 12:08) [22]


> та же самая ерунда с передачей потока

Проблематично очень в dll передавать классы. Да и в любой книжке советуют пользоваться лишь стандартными типами данных.


 
Skier   (2003-05-19 12:21) [23]

>danja (19.05.03 11:57)
Если хочешь использовать объекты именно в параметрах функции DLL, то нужно это делать через интерфейсы, насколько я помню, и с интерфейсами работать...


 
nikkie   (2003-05-19 12:57) [24]

>Я не гордый, я могу и в dpr, и потоки убрал, а таже самая фигня:
после строки параметры передаются неверные!

ну если ты еще скажешь, что у тебя и stdcall везде написано, то останется только руками развести...


 
Юрий Федоров   (2003-05-19 13:03) [25]

>>danja (19.05.03 11:57)
ДУмаю, в данном случае вместо строки лучше передать PChar и не париться со всеми SharaMem"ами


 
danja   (2003-05-19 17:31) [26]

> nikkie
Точно, и stdcall везде написано, и руками разводил - не помогает (хотя в других ветках форума пишут что stdcall в этом случае не обязательно (dll-ка для одного exe-шника - сокрытие реализации))

> Юрий Федоров
Спасибо так и сделаю, тока завтра.

А что с потоками совсем труба? - Ведь, вообщем, только адрес передается. Жалко, даже не знаю как большой объем данных передать.
А с интерфейсами не пробовал - пока не знаю что это такое. :()


 
Юрий Федоров   (2003-05-19 17:50) [27]

Насчет потоков (TStream) - я обычно в таких случаях передаю указатель и размер буффера.
С интерфейсами нужно в данном случае работать очень аккуратно, типичная ошибка - забыть указатель на интерфейс и выгрузить библиотеку, попытка вызова _Release объекту из выгруженной DLL приводит к неприятностям типа AccessViolation


 
_Narayan_   (2003-05-19 20:53) [28]

2 nikkie
это здесь не причём, я тока указатели использую

2 Palladin
Ты о чём ?

Вообще-то я уже разобрался, всё нормально работает


 
Malder   (2003-05-19 21:25) [29]

И в чем было дело ?


 
_Narayan_   (2003-05-20 18:23) [30]

Значит так.
Выдавало ошибку когда я описывал переменную, как экземпляр структуры, и ссылку на этот экземпляр передавал в процедуру (в DLL).
Переделал вот как:
Описываю переменную, как указатель на экземпляр структуры.
Выделяю память под эту переменную New() ,
И передаю эту переменную в процедуру (в DLL).

Всё.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.06.02;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.008 c
1-2922
Disruptor
2003-05-23 06:31
2003.06.02
Пробл. с отчетами - некорр. отображ. QRBand размером > страницы


14-3076
Lopuhh
2003-05-16 12:55
2003.06.02
О БК


14-3056
zhenya
2003-05-15 20:10
2003.06.02
Процессы?


1-2863
sosv
2003-05-20 16:58
2003.06.02
Как отлаживать DLL?


1-2886
123456
2003-05-22 16:36
2003.06.02
ShellExecute





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский