Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
 Re: обращение к DataSet через dll  [new]
Петр
Member

Откуда: Москва
Сообщений: 736
Фэйтл Эра
Петр
надо чтобы из другой программы (язык MQL4) получить последовательность записей запроса Query (select * from table)

Что ж ты сразу не сказал про мкл4.

Фиг тебе, а не интерфейсы.
И, естественно, никаких тебе объектов из dll.
Используй какую-нибудь json или xml или csv для возврата структур. Проще всего возвращать все записи сразу. Ибо иначе тебе придется в длл готовить и хранить контекст запроса. Ничего сложного, просто кодить больше.


На самом деле все работает. Осталась одна проблема: глобальное объявление ADOQuery к которому идет обращение несколько раз пока до дойдем по последней записи.

Так вот вопрос если все методы описанные выше сделать в виде интерфейса или класса - будет создаваться свой экземпляр этого объекта в своем разделе памяти?
24 дек 18, 22:16    [21772513]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3707
Петр
будет создаваться свой экземпляр этого объекта в своем разделе памяти?
В каком своем?
Не надо его нигде объявлять. Его надо создавать и возвращать функцией создания в основную программу. Как хэндл.
24 дек 18, 23:14    [21772527]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
Фэйтл Эра
Member

Откуда:
Сообщений: 416
Петр
Так вот вопрос если все методы описанные выше сделать в виде интерфейса или класса - будет создаваться свой экземпляр этого объекта в своем разделе памяти?

В "своем". :)
Например, такая схема: вызываешь dll метод GetQuery('select ... from ...'), в котором создается TADOQuery и возвращается указатель на него. Далее, для перебора записи используешь, например, метод FetchNext(указатель_на_запрос TADOQuery), который возвращает структуру (xml,json), содержащую текущую запись. Или возвращающую признак EOF, а текущую запись вытягиваешь по отдельному полю, GetField(имя_поля).
Не забыть придумать стратегию обработки ошибок: например, когда коннект обломился или поля такого нет.

И в конце не забыть вызвать метод разрушения объекта. Ручками, до выгрузки dll.
24 дек 18, 23:24    [21772534]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
Петр
Member

Откуда: Москва
Сообщений: 736
Да вы правы, создавать надо из основной программы.

Ну какбы вроде все встало на свои места.

Обработка исключений - это конечно самое тонкое место. Главная проблема обрыв коннекта. Буду думать

Всем спасибо за помощь.
25 дек 18, 00:26    [21772567]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
Петр
Member

Откуда: Москва
Сообщений: 736
решил все таки сделать доступ к компонентам ADO через интерфейс и что-то заблудился в двух соснах, при присвоении интерфейсной переменной получаю runtime error.
для примера набросал проект.
unit prj_test;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   ADODB, StdCtrls;

type
  // Определение интерфейса
  IMQLADO = Interface(IInterface)
  ['{A821E663-27E2-462F-AD1C-96AA200117CE}']
  function OpenConnect(ServerName, DatabaseName:PWideChar):Pointer stdcall;
end;

type
  TMQLADO = Class(TInterfacedObject, IMQLADO)
  private
  public
    function OpenConnect(ServerName, DatabaseName:PWideChar):Pointer stdcall;
end;


type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
{
constructor TMQLADO.Create();
begin
 inherited;
end;
}

function TMQLADO.OpenConnect(ServerName, DatabaseName:PWideChar):Pointer stdcall;
var
 ADOConnection: TADOConnection;
var
  strerr: widestring;
begin
  try
    ADOConnection := TADOConnection.Create(nil);
    ADOConnection.LoginPrompt := false;
    ADOConnection.KeepConnection := false;
    if not ADOConnection.Connected then
     begin
      ADOConnection.Close;
      ADOConnection.ConnectionString := 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=' + DatabaseName + ';Data Source=' + ServerName + ';Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False';
      ADOConnection.ConnectionTimeout := 30;
      ADOConnection.Connected := true;
      result := Pointer(ADOConnection);
     end;
  except
    on e: Exception do
    begin
      strerr := 'ERROR: ' + E.Message;
      result := NIL;
    end;

  end;
 end;
procedure TForm1.Button1Click(Sender: TObject);
var
  IMQL: IMQLADO;
  TMQL: TMQLADO;
begin
  TMQL.Create;
  IMQL := TMQL; // <- RUNTIME ERROR 
end;

end.


Что не так делаю?
4 янв 19, 13:12    [21778336]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
Vlad F
Member

Откуда:
Сообщений: 480
Петр,

Результат выполнения Create чему то присваиваешь?))
4 янв 19, 13:29    [21778341]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
Петр
Member

Откуда: Москва
Сообщений: 736
да затупил
procedure TForm1.Button1Click(Sender: TObject);
var
  IMQL: IMQLADO;
  TMQL: TMQLADO;
begin
  TMQL := TMQLADO.Create;
  IMQL := TMQL;
  IMQL.OpenConnect('(local)', 'MT4');
end;
4 янв 19, 13:37    [21778344]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
Vlad F
Member

Откуда:
Сообщений: 480
Петр,

Ты не лез бы пока в интерфейсы, мил человек, с таким то уровнем базовых навыков (прошу без обид), думаешь они тебе чем то помогут?
4 янв 19, 13:46    [21778348]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
Петр
Member

Откуда: Москва
Сообщений: 736
для вызова переменной интерфейса через DLL, делаю функцию ее создания в DLL
library ptr_mssql;
***
function GetMQLADO(): IMQLADO;
begin
  Result := TMQLADO.Create;
end;

exports

GetMQLADO;

begin

end.


но вызов GetMQLADO из основной программы - опять выдает runtime error

procedure TForm1.Button3Click(Sender: TObject);
var
  IMQL: IMQLADO;
begin
 IMQL := GetMQLADO();
end;

что не так делаю?
4 янв 19, 14:44    [21778386]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
Петр
Member

Откуда: Москва
Сообщений: 736
проблема была в неверном объявлении импортируемой функции
правильный вызов:
***
function GetMQLADO(): IMQLADO; external 'ptr_mssql';
***
procedure TForm1.Button3Click(Sender: TObject);
var
  IMQL: IMQLADO;
begin
 IMQL := GetMQLADO();
end;
4 янв 19, 15:02    [21778400]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
Петр
Member

Откуда: Москва
Сообщений: 736
тестовый пример работает, коннект устанавливается и разрывается:
unit prj_test;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   ADODB, StdCtrls, MQLADO, InterfaceMSSQL, ShareMem;
***
var
  Form1: TForm1;
  HandleConnect: Pointer;
  HandleQuery: Pointer;
  IMQL: IMQLADO;

function GetMQLADO(): IMQLADO; external 'ptr_mssql';

procedure TForm1.Button3Click(Sender: TObject);
begin
 IMQL := GetMQLADO();
 HandleConnect := IMQL.OpenConnect('(local)', 'MT4');
 IMQL.CloseConnect(HandleConnect);
end;

но после закрытия формы основной программы получаю ошибку 'Invalid pointer operation'.
Хотя я так понимаю память интерфейсной переменной сама должна была освободиться. Както дополнительно надо ее освобождать?
4 янв 19, 15:18    [21778406]     Ответить | Цитировать Сообщить модератору
 Re: обращение к DataSet через dll  [new]
ma1tus
Member

Откуда:
Сообщений: 615
Петр
сама должна была
при выходе из зоны видимости переменной. Глобальную переменную - ручками, раньше выгрузки dll
4 янв 19, 19:58    [21778525]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
Все форумы / Delphi Ответить