Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 05.11.2015, 09:18
amspeople amspeople вне форума
Прохожий
 
Регистрация: 05.11.2015
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
Вопрос Перевести код из C++

Есть код:
Код:
char szObjectName[] = "Clipboard";
int irPlg_GetPluginName(char* szBuffer, int* pnBufferSize)
{
	// The proper name of the object as it will appear on the Plugins menu
	int nLength = lstrlen(szObjectName);
	if(*pnBufferSize < nLength)
	{
		*pnBufferSize = nLength;
		return -1;
	} else
	{
		memset(szBuffer,0,*pnBufferSize);
		lstrcpy(szBuffer,szObjectName);
		return nLength;
	}
}
Помогите, плиз, перевести его в Pascal.
Ответить с цитированием
  #2  
Старый 05.11.2015, 19:02
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,090
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Код:
const
  szObjectName : String = 'Clipboard';

function irPlg_GetPluginName(szBuffer : PChar; var pnBufferSize : Integer) : Integer;
var
  nLength : Integer;
begin
  nLength := Length(szObjectName) * SizeOf(Char); // To support unicode and non unicode
  if pnBufferSize < nLength
    Then
      Begin
         pnBufferSize := nLength;
         Result := -1;
      End
    Else
      Begin
        FillChar(szBuffer,pnBufferSize,#0);
        StrCopy(szBuffer,PCHAR(szObjectName));
        Result := nLength;
      End;
end;

Как-то так, если не напутал с параметрами FillChar и StrCpy - проверь по документации.

Последний раз редактировалось lmikle, 07.11.2015 в 23:34.
Ответить с цитированием
  #3  
Старый 05.11.2015, 23:26
amspeople amspeople вне форума
Прохожий
 
Регистрация: 05.11.2015
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

А то, что в параметрах функции вы используете не указатели, как в функции на C++, ничего страшного?
Эта функция будет экспортироваться в DLL. И, вроде как, программа, вызывающая эту функцию будет передавать в параметрах указатель на буфер.

Последний раз редактировалось amspeople, 06.11.2015 в 10:30.
Ответить с цитированием
  #4  
Старый 06.11.2015, 10:17
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

Если для DLL, то для полной совместимости надо заменить String на AnsiString.
Код:
const
  szObjectName : AnsiString = 'Clipboard';
 
function irPlg_GetPluginName(szBuffer : PAnsiChar; var pnBufferSize : Integer) : Integer;
var
  nLength : Integer;
begin
  nLength := Length(szObjectName) * SizeOf(AnsiChar); // To support unicode and non unicode
  if pnBufferSize < nLength
    Then
      Begin
         pnBufferSize := nLength;
         Result := -1;
      End
    Else
      Begin
        FillChar(szBuffer,nLength,#0);
        StrCpy(szBuffer,PAnsiChar(szObjectName),nLength);
        Result := nLength;
      End;
end;
Ответить с цитированием
  #5  
Старый 06.11.2015, 19:00
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,090
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Вася, умный, да?
Читай код внимательно.
1. String используется только внутри модуля, наружу выдается PChar.
2. String использован именно для универсальности - поддерживается unicode и non-unicode версии.
3. Везде наружу "торчат" именно указатели:
PChar - указатель на Char;
var Integer в параметрах функции компилятором транслируется именно в указатель.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
amspeople (07.11.2015)
  #6  
Старый 07.11.2015, 09:26
amspeople amspeople вне форума
Прохожий
 
Регистрация: 05.11.2015
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

lmikle, спасибо за код и разъяснения.
Один момент, Делфи 7 не знает функцию StrCpy. Может подключить в uses что надо? Спасибо.
Ответить с цитированием
  #7  
Старый 07.11.2015, 23:35
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,090
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Sorry, сейчас по справке проверил параметры и имена функций. По ходу, StrCpy я притащил из С-ей. Должно быть вот так:
Код:
        FillChar(szBuffer,pnBufferSize,#0);
        StrCopy(szBuffer,PCHAR(szObjectName));
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
amspeople (08.11.2015)
  #8  
Старый 08.11.2015, 22:05
amspeople amspeople вне форума
Прохожий
 
Регистрация: 05.11.2015
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

lmikle, что-то не работает как надо скомпилированная библиотека.
Когда я пытаюсь вызвать функцию irPlg_GetPluginName из другого языка программирования (lua), то в ее ответе я всегда получаю -1. Какой бы размер буфера я не передал вторым аргументом (даже записывал в буфер нужное число), он почему всегда меньше длины слова szObjectName. Т.е. постоянно срабатывает условие:
Код:
if pnBufferSize < nLength then
У меня есть библиотека, написанная на C++ с этой функцией, и с ней мой код вызова работает корректно. Очевидно, что-то не так с функцией на Паскале.
Ответить с цитированием
  #9  
Старый 09.11.2015, 00:33
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,090
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

А какое значение возвращается в pnBufferSize когда функция возвращает -1?

Есть еще один момент.
Попробуй функцию описать вот так:
Код:
function irPlg_GetPluginName(szBuffer : PAnsiChar; var pnBufferSize : Integer) : Integer; stdcall;
Ответить с цитированием
  #10  
Старый 09.11.2015, 00:38
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
stdcall
Вообще, в C++ по умолчанию cdecl, а в делфи - fastcall. И на экспортируемые функции, по всей видимости, тоже. По крайней мере только что собирал в делфе длл-ку с функцией с кучей аргументов - первые передаются регистрами, стек чистит сама.
Значит, если в оригинальной сишной функции не было явно указано соглашение, то скорее cdecl, а не stdcall. Не упало только потому, что агрумента всего два, и делфийная функция поэтому ничего не чистила, иначе бы стек полетел.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 09.11.2015 в 01:20.
Ответить с цитированием
  #11  
Старый 09.11.2015, 10:06
amspeople amspeople вне форума
Прохожий
 
Регистрация: 05.11.2015
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

lmikle, с указанным соглашением stdcall, можно сказать, все заработало.
Если использовать это действие в коде:
Код:
FillChar(szBuffer, pnBufferSize, #0);
то мое приложение, вызывающее irPlg_GetPluginName, крашится. И, как я выяснил, краш происходит на строчке:
Код:
StrCopy(szBuffer, PCHAR(szObjectName));
Если закомментировать
Код:
FillChar(szBuffer, pnBufferSize, #0);
то все работает как надо.
Возникает вопрос, что не так с вышеуказанным действием?

Upd. Отвечу сам. Верная запись кода будет выглядеть так:
Код:
FillChar(szBuffer^, SizeOf(szBuffer), #0);

Upd2.
И подскажите, плиз, как отключить свободное перемещение курсора в редакторе. Достало уже..

Последний раз редактировалось amspeople, 09.11.2015 в 12:07.
Ответить с цитированием
  #12  
Старый 09.11.2015, 20:15
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,090
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Upd1.
Да, торможу, разименовать указатель надо.
А вот SizeOf(szBuffer) - наверное, вернет правильный размер (ибо Дельфя слищком умная, хотя вот разименовать указатель в данном случае сама не смогла...), но лучше пользоваться переданным значением размера буффера, а именно - pnBufferSize. Т.е. выглядеть должно как-то так:
Код:
FillChar(szBuffer^, pnBufferSize, #0);
В принципе, если вызывающий код сам почистит буффер перед передачей, то и в функции чистить не обязательно.

Upd2. Не понял в чем вопрос... где курсор перемещается??? В каком редакторе???
Ответить с цитированием
  #13  
Старый 09.11.2015, 21:46
amspeople amspeople вне форума
Прохожий
 
Регистрация: 05.11.2015
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Upd2. Не понял в чем вопрос... где курсор перемещается??? В каком редакторе???
В редакторе кода разумеется. В какое бы место я не тыкнул курсор, то там остается каретка. Даже за пределами кода.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 00:40.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025