Не видит UDF функцию

Access Violation, некорректное выполнение запросов или вызовов API, ошибки утилит командной строки, в общем все, что вам мешает работать

Модераторы: kdv, dimitr

Ответить
wordofjustice
Сообщения: 6
Зарегистрирован: 11 мар 2008, 13:26

Не видит UDF функцию

Сообщение wordofjustice » 14 июл 2008, 13:46

Код: Выделить всё

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
Размер базы - маленький

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 14 июл 2008, 14:38

Код: Выделить всё

TEMPBLOB = CREATEBLOBFROMXYZ(X, Y, Z);

armagedon2007
Сообщения: 44
Зарегистрирован: 14 мар 2008, 21:01

Re: Не видит UDF функцию

Сообщение armagedon2007 » 14 июл 2008, 14:45

wordofjustice писал(а):

Код: Выделить всё

procedure CreateBlobFromXYZ(X, Y, Z: PChar; Res: TBLOB); cdecl; export;
[/quote]
как минимум var Res: TBLOB

Gera
Сообщения: 53
Зарегистрирован: 12 мар 2008, 17:34

Сообщение Gera » 14 июл 2008, 14:46

http://www.ibase.ru/devinfo/udf_ok.htm
! char и varchar в InterBase и Firebird имеют свою специфику хранения, поэтому они не являются чистым эквивалентом PChar, это будет видно дальше в примерах. Для самой простой обработки строк всегда декларируйте строковые параметры функций как CSTRING, а в udf работайте с ними как с PCHAR. Передавать в такие функции вы сможете как CHAR так и VARCHAR, без изменения кода udf или объявления функции.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 14 июл 2008, 14:54

да уж. понадекларируют варчаров...

wordofjustice
Сообщения: 6
Зарегистрирован: 11 мар 2008, 13:26

Сообщение wordofjustice » 14 июл 2008, 16:11

Благодарю всех, особенно hvlad за указание моей дурацкой ошибки.
ЗЫ По поводу варчаров исправил, хотя сейчас это не вызвало бы проблем, т.к. это одностороннее преобразование. Спасибо.
ЗЫЫ По поводу варов согласен, с варом будет более правильно, хотя технически все равно передаеться указатель.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 14 июл 2008, 16:48

хотя сейчас это не вызвало бы проблем, т.к. это одностороннее преобразование.
varchar передается не так, как cstring. и разбирать его писателю udf более геморройно, чем cstring.

Gera
Сообщения: 53
Зарегистрирован: 12 мар 2008, 17:34

Сообщение Gera » 15 июл 2008, 14:00

На сколько я понял из исходников 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

dostap
Сообщения: 14
Зарегистрирован: 23 фев 2008, 13:30

Сообщение dostap » 15 июл 2008, 15:40

Потому что старший разряд знаковый и диапазон значений для 16 разрадного целого -32768 .. 32767

Gera
Сообщения: 53
Зарегистрирован: 12 мар 2008, 17:34

Сообщение Gera » 15 июл 2008, 15:45

То, что в SQL все типы знаковые это понятно.
Непонятно почему в UDF длинна передается как беззнаковая

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 15 июл 2008, 19:00

Gera, ну и нафиг такой геморрой, если можно спокойно в udf обрабатывать pchar, а функцию декларировать как cstring?
Блин, вот не лень людям, копать начинают чего-то...

Gera
Сообщения: 53
Зарегистрирован: 12 мар 2008, 17:34

Сообщение Gera » 16 июл 2008, 09:11

Я сам только за передачу строк в UDF как cstring. Просто ради интереса копаюсь.

Ответить