Форум: "Базы";
Текущий архив: 2002.01.17;
Скачать: [xml.tar.bz2];
ВнизDLL & Delphi никак не поймут друг друга, или я их. Найти похожие ветки
← →
Dim (2001-12-14 09:26) [0]Здравствуйте знатоки. Есть проблема которую без Вашей помощи не смогу решить. В общем есть поле в котором хранится адрес человека
Адрес формируется так, на название области, города, улиц и т.д. отводится по 42 символа. Если название меньше, то дополняется пробелами. Чтобы показать оператору адреса людей необходимо выбирать из поля подстоки с позиций 1,43,85,127 и т.д. для этой цели создал DLL в которой описаны две функции (для тестов) SubStr и SubString:
Автор Мадорский Г.В.
Function SubStr(Value : PChar; var Start, Count : Cardinal) : PChar; cdecl;export;
var Cnt : Cardinal;
begin
Result := ib_util_malloc(256);
if (Start + Count) > StrLen(Value) then
Cnt := StrLen(Value) - Start
else
Cnt := Count;
StrMove(Result, Value + Start - 1, Count);
Result := TrimString(Result);
Result[Start + Cnt - 2] := #0;
end;
Код взят с сайта ib_demo.ru
function SubString(InString: PChar; var StartChar, CountChar: Integer): PChar;cdecl;export;
var LenString : Integer;
begin
LenString := StrLen(InString);
Result := InString + LenString;
if (StartChar > 0) and (CountChar >= StartChar) then begin
if LenString >= StartChar then Result := InString + StartChar - 1;
if LenString > CountChar then InString[CountChar] := #0;
end;
end;
Так вот собстенно и проблема. Код предоставленный Мадорским Г.В. работает, но начиная с позиции 43 отсекает несколько последних симвлов, а если строка заканчивается раньше (например на 84,126 и т.д.) то вылетает на ошибку:
A fatal exception occurred during the execution of a user defined function.Access violation. The code attempted to access a virtual address without privilege to do sо.
Второй код начиная с позиции 43 всегда возвращает пусто. На сервере прописано так:
DECLARE EXTERNAL FUNCTION SUBSTRING
CSTRING(4096), INTEGER, INTEGER
RETURNS CSTRING(4096)
ENTRY_POINT "SubString" MODULE_NAME "MyDLL"
DECLARE EXTERNAL FUNCTION SUBSTR
CSTRING(256), INTEGER, INTEGER
RETURNS CSTRING(256)
ENTRY_POINT "SubStr" MODULE_NAME "MyDLL.dll"
Помогите разобраться в чем проблема.
← →
Desdechado (2001-12-14 10:41) [1]Для кода Мадорского необходимо по-другому описать функцию на сервере
DECLARE EXTERNAL FUNCTION SUBSTR
CSTRING(256), INTEGER, INTEGER
RETURNS CSTRING(256) FREE_IT
ENTRY_POINT "SubStr" MODULE_NAME "MyDLL.dll"
Это дает команду серверу освободить память после использования функции, иначе он будет ее поедать очень быстро. Насчет правильности работы - исследуйте, коллега, - функция-то тривиальная.
В коде с ib.demo.ru строка программы
if LenString > CountChar then InString[CountChar] := #0;
отсекает в исходной строке символов все, что находится за правой границей, поэтому перед передачей из хранимой процедуры переменной в UDF, сохрани значение переменной в другой. Кроме того, взят не лучший образец кода. Там есть корректнее, этот будет (ИМХО) допускать утечки памяти.
И еще раз повторюсь: к IB-серверу прилагается ib_udf.dll - там есть уже требуемая функция. Не надо велосипед изобретать.
← →
Dim (2001-12-14 11:13) [2]>Desdechado
Вот для примера строка с адресом:
обл.Самарская <доплнено до 42>|г.Тольятти <доплнено до 42>|ул.Комсомольская<доплнено до 42>|д.22 кв.7
Результат запроса - пусто
select substr(student_address,1,42)||" "||
substr(student_address,43,42)||" "||
substr(student_address,85,42)
from dean_student
where student_id=2767
а если все кочается на 42 или 85 то ошибка:
invalid request BLR at offset 24Implementation limit exceeded block size exceeds implementation restriction.
Где и что не так делаю, вот в чем вопрос.
С уважением, Дмитрий
← →
Desdechado (2001-12-15 16:17) [3]если речь идет о ф-ии из ib_udf.dll, то параметры ее описываются так (взято из справки):
substr(s,m,n) returns the substring of s starting at position m and ending at position n.
Note: This function can receive and return up to 32,767 characters, the limit on an InterBase character string.
DECLARE EXTERNAL FUNCTION substr
CSTRING(80), SMALLINT, SMALLINT
RETURNS CSTRING(80) FREE_IT
ENTRY_POINT “IB_UDF_substr” MODULE_NAME “ib_udf”;
вместо 80 в скобках можно поставить любое нужное число, удовлетворяющее ограничению.
Похоже, по привычке 3-м параметром у тебя написана ДЛИНА подстроки, а ф-я требует номер символа, где подстрока заканчивается. Сразу предупрежу: если укажешь больше, чем есть - вернет пустую строку.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.01.17;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.004 c