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

Вниз

Ошибка при получение данных из dll   Найти похожие ветки 

 
Учусь   (2011-04-10 21:56) [0]

Есть несколько дллок с ресурсами. Имена у них: res1.dll, res2.dll... Подключаю их и получаю из них названия ресурсов так:

procedure my15dll;
var i: Byte;
begin
FreeLibrary(hcDll);

 for i := 0 to 15 do
 begin
 @procLoadCard := nil; hcDll := LoadLibrary(PChar("res"+IntToStr(i)+".dll"));
 if hcDll > HINSTANCE_ERROR then
   begin
     try
     @procLoadCard := GetProcAddress(hcDll, "nameres");
     if @procLoadCard <> nil then  nam := procLoadCard;
     If (Form2.ComboBox2.Text<>StrPas(nam))and(Form2.ComboBox2.Items.IndexOf(StrPas(nam) )<0) then
     Form2.ComboBox2.Items.Add(StrPas(nam));
     except
     end;
   end;
 FreeLibrary(hcDll);
  end;
end;

Так работает, комбобокс заполняется, все ок, НО только если программа запущена из среды, по F9. Если запустить просто из ОС, то виснет на этой процедуре и Win7 ее закрывает, пишет: "программа не отвечает".
Помогите, похоже я тут что-то не то накрутил, подскажите, где что не так?
D5 W7


 
clickmaker ©   (2011-04-10 22:10) [1]

во-первых, зачем несколько раз StrPas(nam)?
потом, зачем FreeLibrary(hcDll) вначале?
что возвращает procLoadCard? PChar, судя по всему? откуда она эту строку берет?
LoadLibrary при ошибке возвращает NULL (0). Ошибку можно получить из GetLastError или SysErrorMessage(GetLastError)


 
_Юрий   (2011-04-10 23:28) [2]


>  except
>      end;


так делать не надо - сокрытие ошибки только добавляет головной боли.


>  FreeLibrary(hcDll);

вызывается даже в случае, если загрузка прошла неуспешно. Нехорошо.

Нужен код библиотечных функций.
Очень похоже на возврат PChar от локальной строки.


 
Учусь   (2011-04-11 12:45) [3]

В dll функция возвращает строку - название хранящегося в ней ресурса:

function nameres :  PChar;  stdcall;
begin
Result := "Resouce 1";
end;

exports
nameres;

{$R *.RES}
{$R res.res}

begin
end.

Код заполнения Комбобокса изменил так:

var
nams : String;
nam : PChar;
procLoadCard : function : PChar;

   @procLoadCard := nil;
    hcDll := LoadLibrary(PChar("res1.dll"));

  if hcDll > HINSTANCE_ERROR then
   begin
     @procLoadCard := GetProcAddress(hcDll, "nameres");

     if @procLoadCard <> nil then  nams := StrPas(procLoadCard);

     If (Form2.ComboBox2.Text<>nams)and(Form2.ComboBox2.Items.IndexOf(nams)<0) then
     Form2.ComboBox2.Items.Add(nams); FreeLibrary(hcDll);
   end;

Но все равно виснет.. Не пойму где ошибка. Как сделать чтобы попроще?


 
clickmaker ©   (2011-04-11 13:00) [4]

вариант 1

procedure nameres(buf: PChar; MaxLen: integer); stdcall;
begin
 StrLCopy(buf, ResName, MaxLen);
end;

usage:

SetLength(nams, MaxLen);
procLoadCard(PChar(names), MaxLen);

вариант 2

function nameres: PChar; stdcall;
begin
 Result := PChar(LocalAlloc(LPTR, Length(ResName)+1);
 StrCopy(Result, ResName);
end;

usage:

ResName := procLoadCard;
...
LocalFree(ResName);


 
Учусь   (2011-04-11 15:29) [5]


> clickmaker ©   (11.04.11 13:00) [4]

Премного благодарен. Разобрался с Вашей помощью:)

На правильном коде проще понять где грабли и как что работает.


 
DiamondShark ©   (2011-04-12 13:15) [6]


> clickmaker ©   (11.04.11 13:00) [4]

Что это, Бэрримор?


> SetLength(nams, MaxLen);
> procLoadCard(PChar(names), MaxLen);

И получить в результате хвост из мусора, если nameres скопировала меньше символов, чем MaxLen.

Зачем такие сложности при возврате константы?


 
clickmaker ©   (2011-04-12 13:47) [7]

> [6] DiamondShark ©   (12.04.11 13:15)

предполагается, что если у чела ник "Учусь", то кроме как с константами ему иметь дело рановато?


 
_Юрий   (2011-04-12 19:32) [8]

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


 
_Юрий   (2011-04-16 10:25) [9]

Ну в общем, помогли найти вариант, при котором ошибка не проявляется.
Все довольны.
Это Прекрасно


 
DiamondShark ©   (2011-04-18 12:09) [10]


> Ну в общем, помогли найти вариант, при котором ошибка не
> проявляется.

Причём, ошибка была стопудово не в том, что описано.
Но разве знахарей это волнует?


 
_Юрий   (2011-04-18 19:58) [11]


> DiamondShark ©   (18.04.11 12:09) [10]
>
>


Я ж говорю - ошибка в соглашении о вызовах  :-)
в библиотеке stdcall, который не указан при вызове



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

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

Наверх





Память: 0.47 MB
Время: 0.003 c
15-1302270240
Palladin
2011-04-08 17:44
2011.07.24
Russian Code Cup


15-1302406131
TUser
2011-04-10 07:28
2011.07.24
А на чем мозилла деньги делает?


15-1302121804
Юрий
2011-04-07 00:30
2011.07.24
С днем рождения ! 7 апреля 2011 четверг


11-1230465048
p.s.
2008-12-28 14:50
2011.07.24
Нестандартная форма (Форма окна по bmp)


15-1302086638
Jan
2011-04-06 14:43
2011.07.24
реально ли в рантайме поменять classname формы или я делаю не так





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