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

Вниз

UDF CString(10)?   Найти похожие ветки 

 
AndrewVolkov   (2003-07-06 16:56) [0]

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

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

текст ДЛЛ


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-06 18:08) [1]

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


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

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


 
Rad   (2003-07-07 07:20) [3]

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


 
Digitman   (2003-07-07 10:44) [4]

вполне легальный для данного случая трюк, позволяющий обойтись без выделения памяти под результат и, соответственно, без 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"


 
AndrewVolkov   (2003-07-07 12:19) [5]

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


 
Digitman   (2003-07-07 12:30) [6]


> AndrewVolkov


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


 
AndrewVolkov   (2003-07-07 12:33) [7]

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


 
AndrewVolkov   (2003-07-07 13:05) [8]

то Rad

extern void * ib_util_malloc (long);

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


 
Digitman   (2003-07-07 13:07) [9]

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

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

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

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

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

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

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

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


 
AndrewVolkov   (2003-07-07 13:36) [10]

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

Спасибо.



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

Форум: "Базы";
Текущий архив: 2003.07.28;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.006 c
7-91930
iliann
2003-05-16 22:50
2003.07.28
мышь


1-91753
Yurko
2003-07-15 16:19
2003.07.28
Формат даты


3-91621
Step[B.M.]
2003-07-04 08:51
2003.07.28
Как организовать цикл по записям в процедуре InterBase


3-91682
Alexandr CH_
2003-07-07 12:18
2003.07.28
Создание файла dbf (локально)


11-91699
Bartov
2002-11-22 14:51
2003.07.28
ImageList





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