Страница 1 из 1
Не видит UDF функцию
Добавлено: 14 июл 2008, 13:46
wordofjustice
Код: Выделить всё
procedure CreateBlobFromXYZ(X, Y, Z: PChar; Res: TBLOB); cdecl; export;
var
TempStr: String;
begin
TempStr := String(X) + String(Y) + String(Z);
if not Assigned(Res.Handle) then Exit;
Res.PutSegment(Res.Handle, PChar(TempStr), Word(Length(TempStr)));
end;
Экспорт в дллке есть. Дллка та, другие функции работают, других копий нет, без отключения базы заместить не получаеться и т.д. Уверенность что это именно та дллка которая используеться базой есть.
Код: Выделить всё
DECLARE EXTERNAL FUNCTION CREATEBLOBFROMXYZ
VARCHAR(40),
VARCHAR(40),
VARCHAR(40),
BLOB
RETURNS PARAMETER 4
ENTRY_POINT 'CreateBlobFromXYZ' MODULE_NAME 'MultiStoreDbSec';
Великолепно регистрирует этот новый вход.
А вот на процедуру в которую вставляеться вызов:
Код: Выделить всё
...
CREATEBLOBFROMXYZ(X, Y, Z, TEMPBLOB);
...
Ругаеться, причем вначале комитит (IBExpert), но потом вылезает отдельное модальное окошко с ошибкой:
Код: Выделить всё
Invalid data type, length, or value.
function CREATEBLOBFROMXYZ could not be matched.
Пробовал все идентификаторы через копипаст привести к одному знаменателю - не помогает. Посоветуйте что еще проверять?
ОС - WinXP SP2
FB - 2.1.0.17735
Размер базы - маленький
Добавлено: 14 июл 2008, 14:38
hvlad
Re: Не видит UDF функцию
Добавлено: 14 июл 2008, 14:45
armagedon2007
wordofjustice писал(а):Код: Выделить всё
procedure CreateBlobFromXYZ(X, Y, Z: PChar; Res: TBLOB); cdecl; export;
[/quote]
как минимум var Res: TBLOB
Добавлено: 14 июл 2008, 14:46
Gera
http://www.ibase.ru/devinfo/udf_ok.htm
! char и varchar в InterBase и Firebird имеют свою специфику хранения, поэтому они не являются чистым эквивалентом PChar, это будет видно дальше в примерах. Для самой простой обработки строк всегда декларируйте строковые параметры функций как CSTRING, а в udf работайте с ними как с PCHAR. Передавать в такие функции вы сможете как CHAR так и VARCHAR, без изменения кода udf или объявления функции.
Добавлено: 14 июл 2008, 14:54
kdv
да уж. понадекларируют варчаров...
Добавлено: 14 июл 2008, 16:11
wordofjustice
Благодарю всех, особенно hvlad за указание моей дурацкой ошибки.
ЗЫ По поводу варчаров исправил, хотя сейчас это не вызвало бы проблем, т.к. это одностороннее преобразование. Спасибо.
ЗЫЫ По поводу варов согласен, с варом будет более правильно, хотя технически все равно передаеться указатель.
Добавлено: 14 июл 2008, 16:48
kdv
хотя сейчас это не вызвало бы проблем, т.к. это одностороннее преобразование.
varchar передается не так, как cstring. и разбирать его писателю udf более геморройно, чем cstring.
Добавлено: 15 июл 2008, 14:00
Gera
На сколько я понял из исходников FB (fbudf.cpp), в Dll-ку Varchar передается как
Код: Выделить всё
struct vvary
{
fb_len vary_length;
ISC_UCHAR vary_string[max_varchar_size];
};
Код: Выделить всё
typedef USHORT ISC_USHORT;
typedef ISC_USHORT fb_len;
typedef unsigned char ISC_UCHAR;
const int varchar_indicator_size = sizeof(ISC_USHORT);
const int max_varchar_size = 65535 - varchar_indicator_size; // in theory
то есть в Pascal'е это будет
Код: Выделить всё
Type vvary = Record
vary_length: Word;
vary_string: Array[65535 - SizeOf(Word)] Of Char;
End
Только не совсем понятно, почему в UDF Varchar, теоретически, может быть 65533, а в SQL 32765
Добавлено: 15 июл 2008, 15:40
dostap
Потому что старший разряд знаковый и диапазон значений для 16 разрадного целого -32768 .. 32767
Добавлено: 15 июл 2008, 15:45
Gera
То, что в SQL все типы знаковые это понятно.
Непонятно почему в UDF длинна передается как беззнаковая
Добавлено: 15 июл 2008, 19:00
kdv
Gera, ну и нафиг такой геморрой, если можно спокойно в udf обрабатывать pchar, а функцию декларировать как cstring?
Блин, вот не лень людям, копать начинают чего-то...
Добавлено: 16 июл 2008, 09:11
Gera
Я сам только за передачу строк в UDF как cstring. Просто ради интереса копаюсь.