Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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.003 c
6-52635
ant_prg
2001-10-23 17:07
2002.01.17
TNMHTTP


14-52657
Polevi
2001-11-23 10:14
2002.01.17
Дежавю


1-52585
Марина
2001-12-29 09:05
2002.01.17
Минимизация формы


14-52649
vic_vm
2001-11-21 13:48
2002.01.17
Плакат


1-52574
Марина
2001-12-28 10:28
2002.01.17
SysTray или RxTrayIcon





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