Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 ORA_FFI и строковый тип данных в DLL на Delphi - Forms вылетает  [new]
shurikt
Member

Откуда: Казахстан
Сообщений: 273
Имеется:
- Oracle Forms 10.1.2.0.2
- Application Server 10.1.2.2 настроенный на работу через Java Plug-in 1.5.0_15
- Библитека DLL Созданная на Delphi 7 с функцией в ней:
function test(i: double; var a: String ): double;
begin
  a:='zzz';
  Result:=i+2;
end;
При обращении к этой функции через Ora_FFI в Forms форма аварийно завершается с ошибкой FRM-92101.

Что интересно стоит закомментировать в функци
{a:='zzz';}
и форма прекрасно работает и возвращает приращенный на 2 аргумент.
Подозреваю что это связано с типом данных. Пробовал аргументу а ставить типы: PChar, ShortString, Char - безрезультатно.
Есть идеи?
23 май 08, 13:25    [5706332]     Ответить | Цитировать Сообщить модератору
 Re: ORA_FFI и строковый тип данных в DLL на Delphi - Forms вылетает  [new]
shurikt
Member

Откуда: Казахстан
Сообщений: 273
Переделал процедуру в такой вид:
function test(a: PChar ): PChar;
begin
  Result:=a;
end;

форма не вылетает, но выдает ерунду всякую (три разных символа), притом при каждом повторном вызове выдается новый результат для одного и того же аргумента
Это если указываю тип параметра C_CHAR_PTR в ora_ffi.Register_Paramrter и Register_Return.

А если указываю тип C_CHAR, то всегда и для разных аргументов получаю "м".
Признаюсь в дельфи новичек. Да и в типах данных слабоват, все больше Oracle. :-)
23 май 08, 15:06    [5707234]     Ответить | Цитировать Сообщить модератору
 Re: ORA_FFI и строковый тип данных в DLL на Delphi - Forms вылетает  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 9249
Выкинь возврат результата!

Функцию преврати в процедуру. Возврашаей результат через IN/OUT входной параметр, ВСЕГДА инициализуруя его до вызова твоей функции (что бы был буффер, куда данные записывать)
23 май 08, 15:40    [5707525]     Ответить | Цитировать Сообщить модератору
 Re: ORA_FFI и строковый тип данных в DLL на Delphi - Forms вылетает  [new]
shurikt
Member

Откуда: Казахстан
Сообщений: 273
Спасибо Леонид, начал делать как Вы посоветовали и похоже начало работать как я хотел - добавил параметру var, т.е. написал:
function test(var a: PChar ): PChar;
begin
  Result:=a;
end;
и передаваемое значение стало возвращаться.

Теперь буду усложнять функцию для решения своей задачи.
23 май 08, 15:56    [5707669]     Ответить | Цитировать Сообщить модератору
 Re: ORA_FFI и строковый тип данных в DLL на Delphi - Forms вылетает  [new]
shurikt
Member

Откуда: Казахстан
Сообщений: 273
только все же интересно почему заработало от var?
23 май 08, 15:58    [5707680]     Ответить | Цитировать Сообщить модератору
 Re: ORA_FFI и строковый тип данных в DLL на Delphi - Forms вылетает  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 9249
Блин. Я имел в виду совсем другое.

Вместо функции, используеш ПРОЦЕДУРУ. Результат возврашаеш, через IN/OUT параметры.

Типа:

(на C)

void my_function( char *p_in_string, char *p_out_string ) {
strcpy( p_out_string, "SOURCE PARAMETER = \"");
strcat( p_out_string, p_in_string );
strcat( p_out_string, "\"" );
}


В вызывающем PL/SQL коде:

declare
x_in varchar2(2000);
x_out varchar2(2000);
begin
x_in := 'A source string';
/* Выделяем буффер в памяти для возврата результата */
x_out := lpad( '*', '*', 2000 );
/* Вызываем нашу функцию */
ff_my_function( my_function_fhandle, x_in, x_out );
/* Выводим результат на экран */
Message( x_out );
Message( ' ', NO_ACKNOWLEDGE );
end;

Могут быть ошибки, т.к. это не рабочей пример (не компилировал, не проверял). Да и вообще, с ORA_FFI последние 2 года дела не имел.
25 май 08, 16:39    [5712033]     Ответить | Цитировать Сообщить модератору
 Re: ORA_FFI и строковый тип данных в DLL на Delphi - Forms вылетает  [new]
!делфист
Guest
shurikt
только все же интересно почему заработало от var?


Потому что тип string - это очень хитрый внутренний тип Delphi, с реализованным счетчиком и сбором мусора, управляемый специальным (делфийским) менеджером памяти.
И именно по-этому просто запрещено тип string (а также объектные ссылки) передавать в dll в
целях обработки (присваивания, вызова) в них (даже если dll и вызывающая программа - писаны на Delphi).
Т.е. происходит конфликт двух параллельно работающих менеджеров памяти, в результате -
просиходит протирка кучи (heap) всяким мусором, с непредсказуемыми результатами.

Говоря проще - см. внимательно на допустимые типы данных в DLL (расписаны в документации по Delphi в т.ч.).

Кроме того, у тебя еще каша в голове на декларирование порядка передачи параметров в DLL
(хоть не уверен, что там в Forms принято - cdecl или pascal).
25 май 08, 16:54    [5712057]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить