Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

UDF CString(10)? [D7, IB6.x]


AndrewVolkov ©   (2003-07-06 16:56:00) 

Доброго всем дня.

Первый раз написал ДЛЛ и сразу в непонятках

текст ДЛЛ


library LppDll;


uses
SysUtils;
function malloc(Size:Integer) : Pointer; cdecl; external "msvcrt.dll";

function CharToWord(sz: PChar) : PChar; cdecl; export;
Var Str:String;
begin
Str:=(sz);
if Str="0" then Str:="No"
else if Str="1" then Str:="Yes"
else Str:="No";

Result:=malloc(length(Str)+1);
StrPCopy(Result, Str);
end;
exports
CharToWord;
begin
end.


ее декларация

DECLARE EXTERNAL FUNCTION CHARTOWORD
CSTRING(10)
RETURNS CSTRING(10) FREE_IT
ENTRY_POINT "CharToWord"
MODULE_NAME "lppdll.dll"


Для Грида Source -> ibQuery а у него View Interbase, где соответственно я использую CharToWord(q11) к примеру

Все отлично работает, только трабла в следующем когда я в ibQuery через правую кнопку добавляю поле q11 - у него размер 254. И в гриде в ячейке если расположение стоит право или центр я ничего не вижу. Если меняю дисплей сайз для поля - не помогает. если ставлю сайз -10, то при отрисовке гриде вылетает с ошибкой что не может в размер 10 уместить данные. Почему???
Ведь в декларации функции я указал вход 10 символов и выход 10, откуда он берет 254???


AndrewVolkov   (2003-07-07 13:36:00) [1]

Да...
Без пива не разберусь...

Спасибо.


Digitman   (2003-07-07 13:07:00) [2]

в двух словах :

- IB и его клоны перед вызовом UDF создают в памяти временные копии факт.параметров;

- менеджер памяти сервера всегда аллокирует память блоками не менее 4-х байт (выравнивание);

- сформированные копии параметров всегда передаются в UDF по ссылке;

- копии параметров уничтожаются сервером после получения результата вызова UDF;

- строковые результаты по умолчанию всегда передаются по ссылке.

т.о., если в UDF параметром передается строка "1", то :
- сервер выделит память размером не менее 4 байта (память под дескриптор не учитываем);
- скопирует в эту память строку "1"#0;
- адрес буфера копии передаст параметром cstring(не важно сколько);
- UDF берет этот адрес и записывает по нему результат своего выполнения, т.е. строку "Yes"#0, благо размер ее, включая терминирующий "ноль", не превышает 4 байта;
- UDF возвращает результат в виде адреса, совпадающего с адресом копии переданного факт.параметра;
- сервер, получив результатом адрес строки, копирует строку (неважно, что ее адрес совпадает с адресом копии параметра - параметр еще "жив" !) куда требуется, и после этого уничтожает копию факт.параметра.

Вот и вся "кухня" трюка)


AndrewVolkov   (2003-07-07 13:05:00) [3]

то Rad

extern void * ib_util_malloc (long);

В моем IB она называется вот так.


AndrewVolkov   (2003-07-07 12:33:00) [4]

Ну если честно то не совсем я понял его отличие. Если бы в двух словах, был бы очень признателен


Digitman   (2003-07-07 12:30:00) [5]


> AndrewVolkov


главное - понять, чем данныйслучай отличается от прочих


AndrewVolkov   (2003-07-07 12:19:00) [6]

Спасибо - учту...
Интересное замечание..


Digitman   (2003-07-07 10:44:00) [7]

вполне легальный для данногослучая трюк, позволяющий обойтись без выделения памяти под результат и, соответственно, без free_it


library LppDll;

uses
SysUtils;

function CharToWord(sz: PChar) : PChar; cdecl;
begin
Result := sz;
try
if String(sz) ="1" then
StrPCopy(Result, "Yes")
else
StrPCopy(Result, "No");
except
Result := nil;
end;
end;

exports
CharToWord;
begin
IsMultiThread := True; //!!!!!!!
end.


декларация


DECLARE EXTERNAL FUNCTION CHARTOWORD
CSTRING(10)
RETURNS CSTRING(10)
ENTRY_POINT "CharToWord"
MODULE_NAME "lppdll.dll"


Rad   (2003-07-07 07:20:00) [8]

Рекомендация для совместимости UDF с разными версиями FB/Ya/IB:
замени mallocна ib_mallocиз ib_util.dll. А то, к примеру, в Ya используется msvcrt7.dll. Ну и о многоплатформенности, опять же, не стоит забывать.


AndrewVolkov   (2003-07-06 18:57:00) [9]

Незнаю что произошло, но после рестарта все зарулило намано.
Вопрос снимаю...


AndrewVolkov   (2003-07-06 18:08:00) [10]

Уточнение...
Если делать select from table
то все нормально с размерами, а если из View То размер становиться сразу 254


Наверх

Титульная страница Поиск, карта сайта Написать письмо