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

Вниз

Ошибка при вызове dll   Найти похожие ветки 

 
Вульфович Филипп   (2010-04-05 12:43) [0]

Добрый день! У меня есть dll, которая работает с некоторым устройством (пинпадом).

Я линкую ее статически:


//Создание служебного объекта
function eftp_create(szConfigPath: PChar):Pointer; stdcall; external DllLibraryName;
//Освобождение служебного объекта
procedure eftp_destroy(pvSelf:Pointer);stdcall; external DllLibraryName;
//Отправка-прием данных
function eftp_do(pvSelf:Pointer;pchInBuffer:PChar; pchOutBuffer:PChar;
           pfldle:pointer;pvData:pointer):integer; stdcall; external DllLibraryName;


Я сделал тестовую программку: форму с кнопкой.
Проблема в том ,что
если я вызываю функции dll так:


procedure TForm1.Button1Click(Sender: TObject);
var
 UcsObj: Pointer;
begin
 UcsObj:=eftp_create(СonfigPath);  
 eftp_do(UcsObj, PChar(S1), S2, nil, nil);
 eftp_destroy(UcsObj);
end;


То все работает прекрасно!

Но если я пытаюсь поместить процедуру eftp_create в другую процедуру, возникает ошибка "Privileged instruction", вот
код, который не работает:



procedure TForm1.Button1Click(Sender: TObject);
var
 UcsObj: Pointer;

procedure CreateObj;
begin
 UcsObj:=eftp_create(СonfigPath);  
end;

begin
 eftp_do(UcsObj, PChar(S1), S2, nil, nil);
 eftp_destroy(UcsObj);
end;



При выполнении eftp_create ошибки не происходит, а ошибка Privileged Instruction возникает при выходе из процедуры Test.

То же самое, если я создаю служебный класс



interface

 TEFTPServiceObject = class
 private
   UcsObj: Pointer;
 public
   procedure CreateObject(ConfigPath: string);
 end;

implementation

procedure TEFTPServiceObject.CreateObject(ConfigPath: string);
begin
  UcsObj:=eftp_create(СonfigPath);
end;

...



Вызов eftp_create нормально проходит внутри метода CreateObject, но после возвращения из
из метода CreateObject та же ошибка: Privileged Instruction

Помогите разобраться. Получается я не могу воспользоваться ни структурным программирование, ни тем более объектно-ориентированным.

Сейчас буду пробовать вызывать dll динамически через LoadLibrary, может быть заработает. Но хочется разобраться, почему и статическое линкование работает как-то очень плохо.

Спасибо!


 
Slym ©   (2010-04-05 13:15) [1]

судя по всему содержимое СonfigPath в eftp_create не копируется, а сохраняется ссылка...
при выходе из процедуры строка затирается...
прпробуй глобально объявить:
var СonfigPath="c:\"; или const СonfigPath="c:\";
или
TEFTPServiceObject = class
private
  FСonfigPath:string;
  UcsObj: Pointer;
public
  procedure CreateObject(const ConfigPath: string);
end;
procedure TEFTPServiceObject.CreateObject(const ConfigPath: string);
begin
FСonfigPath:=ConfigPath;
UcsObj:=eftp_create(FСonfigPath);
end;


 
Вульфович Филипп   (2010-04-05 13:42) [2]

Да, но так тоже не работает! Куда проще?

procedure TForm1.Button1Click(Sender: TObject);
var
UcsObj: Pointer;

procedure CreateObj;
begin
UcsObj:=eftp_create("C:\test.cfg");  
end;

begin
 CreateObj;
 eftp_do(UcsObj, PChar(S1), S2, nil, nil);
 eftp_destroy(UcsObj);
end;


 
Игорь Шевченко ©   (2010-04-05 13:57) [3]

UniqueString не спасет ?


 
Дмитрий Белькевич   (2010-04-05 14:39) [4]


> При выполнении eftp_create ошибки не происходит, а ошибка
> Privileged Instruction возникает при выходе из процедуры
> Test.


Есть подозрение, что проблема в передаче параметров в/из длл.

Скорее всего рушится стёк.


 
12 ©   (2010-04-05 15:38) [5]


> procedure CreateObj;
> begin
> UcsObj:=eftp_create("C:\test.cfg");  
> end;

=eftp_create(Pchar("C:\test.cfg"));  ?


 
Вульфович Филипп   (2010-04-05 17:43) [6]


> Есть подозрение, что проблема в передаче параметров в/из
> длл.
>
> Скорее всего рушится стёк.


Так и есть. Нужно было переопределить функции:



//Создание служебного объекта
function eftp_create(szConfigPath: PChar):Pointer; cdecl; external DllLibraryName;
//Освобождение служебного объекта
procedure eftp_destroy(pvSelf:Pointer);cdecl; external DllLibraryName;
//Отправка-прием данных
function eftp_do(pvSelf:Pointer;pchInBuffer:PChar; pchOutBuffer:PChar;
          pfldle:pointer;pvData:pointer):integer; cdecl; external DllLibraryName;



Но как я мог подумать, что разработчик dll будет cdecl, вместо стандартной stdcall?

:)


 
Дмитрий Белькевич   (2010-04-05 18:22) [7]


> Но как я мог подумать, что разработчик dll будет cdecl,
> вместо стандартной stdcall?


Бывает ;) Когда валится на end"ах - верный признак, что стёк кто-то рушит.


 
Игорь Шевченко ©   (2010-04-05 19:47) [8]

Never attribute to malice which can adequately be explained by stupidity


 
Германн ©   (2010-04-06 01:32) [9]


> Но как я мог подумать, что разработчик dll будет cdecl,
> вместо стандартной stdcall?

Если я не ошибаюсь, то если в Си не указывать явно соглашение о вызовах, то будет именно cdecl. А в Delphi будет pascal. И об этом нужно всегда помнить, если речь идет о нестандартных dll.


 
Amoeba_   (2010-04-06 12:03) [10]


> А в Delphi будет pascal.

Слегка ошибаешься. По умолчанию в Delpi будет register а не pascal.


 
evvcom ©   (2010-04-07 11:10) [11]

По-моему, это называется fastcall


 
Amoeba_   (2010-04-07 11:45) [12]


> evvcom ©   (07.04.10 11:10) [11]

И то и другое правильно. register и fastcall - это всего лишь разные названия одного и того же способа передачи параметров. В старых версиях Delphi - register, в более новых - переименовали в fastcall.


 
evvcom ©   (2010-04-08 09:52) [13]

Старые, более новые - понятия весьма расплывчатые...
По-моему, название fastcall я вычитывал еще в какой-то книжке по Delphi 2, а уж 2-ю версию никак не назовешь более новой, хотя могу и ошибаться, столько лет уже прошло, может и позже читал. А про register тоже где-то читал, уже толком не помню что и из-за того, что этот термин практически не употреблялся, деталей про него не помню. Хотя да, было в памяти, что это или то же самое или очень похожее на fastcall :)


 
Amoeba_   (2010-04-08 12:25) [14]

Ну, возможно, было и наоборот. Во всяком случае, начиная с D4 используется название register.
fastcall - это тот же самый register, кроме как в названии абсолютно никакой разницы нет.



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

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

Наверх





Память: 0.48 MB
Время: 0.004 c
2-1310461223
Abibas
2011-07-12 13:00
2011.10.30
Вопрос по keybd_event


2-1310381051
leon2011
2011-07-11 14:44
2011.10.30
Помогите разобраться с TextOutW


1-1270107962
Delp
2010-04-01 11:46
2011.10.30
Вопрос по парсингу xml-файлов


15-1309505832
Andy BitOff
2011-07-01 11:37
2011.10.30
Поправка к вакансии


15-1309513713
Дмитрий
2011-07-01 13:48
2011.10.30
перевод фразы





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