Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Delphi & DOA / 13 сообщений из 13, страница 1 из 1
22.10.2003, 12:21
    #32301224
NetFantom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
Вопрос для тех кто пишет программы на Delphi для СУБД Oracle с использованием Direct Oracle Access:
как можно передать сессию DOA в DLL или ActiveX?
Вообщем я знаю несколько вариантов но ни один у меня почему-то не работает.
Хотелось бы узнать ваши способы, если нет то позже изложу суть своих проблемм - может кто поймет в чем дело =)
...
Рейтинг: 0 / 0
22.10.2003, 12:41
    #32301272
Speaker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
Тут где то пробегало - eNose вроде говорил, что можно делать
приведение к Integer и обратно, то есть передавать в DLL
Integer(TOracleSession), а там делать TOracleSession(значение).

P.S. поиск тебе поможет.
...
Рейтинг: 0 / 0
22.10.2003, 12:53
    #32301297
olga1999
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
Почитай документацию. Там сказано, что у сессии есть свойство ExternalSvc.
Это и есть указатель на сессию. В Dll создаешь новую сессию и ей присваиваешь переданный указатель.
...
Рейтинг: 0 / 0
22.10.2003, 12:56
    #32301304
olga1999
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
Выдержка из документ-ции

TOracleSession.ExternalSVC
Declaration
property ExternalSVC: Pointer;
Description
Runtime property to attach the TOracleSession to a Net8 service context handle of another host program, or to access the service context handle of the session. When you set this property, it is equivalent to calling the LogOn method. Setting ExternalSVC to nil is equivalent to calling LogOff.
This property may be useful when working with Dynamic Link Libraries, though it it usually better and easier to use the Share procedure.
...
Рейтинг: 0 / 0
22.10.2003, 13:15
    #32301347
eNose
Участник
[не активирован]
[не одобрен]
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
DOA Manual: TOracleSession.Share

Передаешь в DLL свой TOracleSession (назовем его OS_App).
В DLL-ке, естественно, создаешь свой TOracleSession (пусть будет OS).
И делаешь OS_App.Share(OS).
Главное, чтобы OS_App уже был Connected.




eNose
...
Рейтинг: 0 / 0
22.10.2003, 13:31
    #32301374
olga1999
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
To ENose
Но при этом будет активно 2 сессии, а в моем варианте - одна.
...
Рейтинг: 0 / 0
22.10.2003, 13:38
    #32301385
eNose
Участник
[не активирован]
[не одобрен]
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
olga1999 писал:Но при этом будет активно 2 сессии, а в моем варианте - одна.
Если не использовать многпоточность (Threaded = False) у наследников от TOracleQuery, TOracleTable, etc., то на сервере будет ОДНА сессия.



eNose
...
Рейтинг: 0 / 0
22.10.2003, 14:44
    #32301535
NetFantom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
Хорошо, теперь простенький пример:
HostApplication который вызывает DLL-ку.
На форме экземпляр OracleSession1 : TOracleSession и Button1:TButton.
По нажатию на кнопку происходит загрузка DLL и вызов функции Init и передается ExternalSVC:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
procedure TForm1.Button1Click(Sender: TObject);

type
  PInitDLL = procedure(p: pointer);
var
  hDLLInst: THandle;
  InitDLL : PInitDll;
begin
  hDLLInst :=  0 ;
  AppSession.LogOn;
  if AppSession.Connected then
  try
    hDLLInst:= LoadLibrary('DLL_Doa_Share.DLL');
    if (hDLLInst <=  0 ) then
    raise exception.create('[Неудачный вызов LoadLibrary]');

    @InitDLL := GetProcAddress(hDLLInst,'Init');
    if not assigned(InitDLL) then
    raise exception.Create('[Неудачный вызов GetProcAddress]');

    InitDll(AppSession.ExternalSVC);
  finally
    FreeLibrary(hDLLInst);
  end;
end;


Теперь код 'DLL_Doa_Share.DLL':
DLL_Doa_Share.dpr
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
library DLL_Doa_Share;

uses
  SysUtils,
  Classes,
  Unit_DLL in 'Unit_DLL.pas' {Form1};
Exports
   init;

{$R *.RES}

begin
end.

*********
Unit_DLL.pas
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
unit Unit_DLL;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Oracle, StdCtrls;
procedure Init(p : pointer); stdcall;

implementation

procedure Init(p : pointer); stdcall;
var OS : TOracleSession;
begin
  OS := TOracleSession.Create(Application);
  OS.ExternalSVC := p;
 // if OS.Connected then ShowMessage('Connected');
  ShowMessage(OS.ServerVersion);
end;
end.



Так вот, все передано как завещал дедушка Ленин (документацию я тоже читал =), и вроде как даже свойсво Connected установилось, НО при вызове метода ServerVersion (впрочем как и равно при попытке выполнить ЛЮБОЙ SQL запрос на основе сессий) OS мы получаем Exception с пустым текстом. Даже номер эксепшина выбить не удается!
...
Рейтинг: 0 / 0
22.10.2003, 14:52
    #32301556
NetFantom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
P.S.
С Share вообще замарачиваться не хочется, т.к. он будет работать только если мы компилируем и хост-приложение и библиотеку на одной и той же версии Delphi да к тому же с одной и той версии DOA, т.к. мы передаем через границу ссылку на объект.
К тому же, у меня если честно этот метод не срабатывает - видимо я неправильно оформляю DLL, т.к. переданная через границу ссылка какая-то странная. По крайней мере св-ва переданного объекта удивительные, видимо не в ту область памяти смотрит =)

Сразу забегая вперед скажу что есть еще метод с передачей набора данных:
nvhp, errhp, secerrhp, svchp, Authp, srvhp и ExternalSVC.
Правда, nvhp, errhp, secerrhp, svchp, Authp, srvhp в private секции, но мы легко можем это обойти создав прямого потомка от TOracleSession:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
type
  TMyOracleSession = class(TOracleSession)
end;
.....
OS:TOracleSession;
.....
TMyOrcaleSession(OS).nvhp := ...
TMyOrcaleSession(OS).errhp := ...
.....


Но результат я получаю аналогичный тому что описал в примере выше.
...
Рейтинг: 0 / 0
22.10.2003, 15:01
    #32301576
NetFantom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
Господа, прошу прощения - паника отменяется.
Я или тормоз или просто нужно кофе - проблемма не с Oracle DOA или Delphi а в моем генетическом коде =)
Пока выкладывал исходные тексты заметил банальную ошибку.
Кто тоже заметит - тому леденец =)
...
Рейтинг: 0 / 0
22.10.2003, 15:03
    #32301586
eNose
Участник
[не активирован]
[не одобрен]
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
NetFantom писал:С Share вообще замарачиваться не хочется, т.к. он будет работать только если мы компилируем и хост-приложение и библиотеку на одной и той же версии Delphi да к тому же с одной и той версии DOA, т.к. мы передаем через границу ссылку на объект.
К тому же, у меня если честно этот метод не срабатывает - видимо я неправильно оформляю DLL, т.к. переданная через границу ссылка какая-то странная.
Насчет одной версии делфей и DOA - неправда. Все прекрасно работает, так как метод share существует с первых версий DOA и никуда из них не денется.
Передавать в DLL надо "тупо":
procedure MyDLLProc(AppHandle: integer; OS: TOracleSession);




eNose
...
Рейтинг: 0 / 0
22.10.2003, 15:14
    #32301607
Speaker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
вот это: @InitDLL := GetProcAddress(hDLLInst,'Init'); ?
...
Рейтинг: 0 / 0
22.10.2003, 15:28
    #32301650
NetFantom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Delphi & DOA
eNose писал:Насчет одной версии делфей и DOA - неправда. Все прекрасно работает, так как метод share существует с первых версий DOA и никуда из них не денется.

Не совсем так. Если хост скомпилирован в одной версии DOA а DLL в другой, то метод Share никуда не денется, но ведь может измениться состав самого интерфейся - тип и набор полей и т.д. И вот тогда очень велика вероятность того что мы получим ошибку т.к. состав класса изменился.

2Speaker и всем кому любопытно =)

Конечно проблемма не в этом - DLL вызывается, иначе бы я получил Exception гораздо раньше. Но дело в вызове процедуры Init.
Дело в том что я объявил в DLL эту функцию как stcall а в описании прототипа в host-application забыл:
Код: plaintext
1.
     type
  PInitDLL = procedure(p: pointer);


А по дефолту она стала register. В результате вызывающая часть передавала параметр в регистре, а DLL ожидала ее в стеке =)
Так что все решение - приведение к общему формату вызова, например stdcall
Код: plaintext
1.
type
  PInitDLL = procedure(p: pointer);stdcall;


Так что тут тока виновата невнимательность...вот такие неявные сюрпризы.
Тем не менее всем спасибо =)
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Delphi & DOA / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]