Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 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-м параметром у тебя написана ДЛИНА подстроки, а ф-я требует номер символа, где подстрока заканчивается. Сразу предупрежу: если укажешь больше, чем есть - вернет пустую строку.




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




Наверх





Память: 0.73 MB
Время: 0.017 c
3-52492           Dim                   2001-12-14 09:26  2002.01.17  
DLL & Delphi никак не поймут друг друга, или я их.


3-52454           Анастасия             2001-12-13 18:51  2002.01.17  
Помогите, пожалуйста, срочно!!!


1-52594           Yuri Btr              2001-12-29 10:40  2002.01.17  
Помогите пожалуйста с импортом DLL


1-52530           навичек               2001-12-27 07:41  2002.01.17  
Дурацкая пошаговая отладка :(


1-52580           Andrey Sharapow       2001-12-27 11:13  2002.01.17  
Нужна идея !!!