powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / обращение к DataSet через dll
25 сообщений из 37, страница 1 из 2
обращение к DataSet через dll
    #39751861
Петр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача написать DLL обертку для работы с датасетом (используется TADOQuery).
Есть внешнее приложение в котором нужно вернуть последовательно строки датасета, для последующей обработки.
Работа с датасетом идет через DLL
Как сделать обертку для метода ADOQuery.Next ?

Т.е. из внешнего приложения код будет такого вида:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
// передача и выполнение запроса в DLL и возвращение хендла
handle := <set_sql_query('select * from table', var <кол столбцов>)> 

while (not <sql_query.EOF(handle)>) // пока есть необработанная строка в датасете
begin
  // получаем значение столбцов текущей строки 
  volum_column1 := get_volum_column1(handle, 1);
  volum_column2 := get_volum_column2(handle, 2);
  volum_column3 := get_volum_column3(handle, 3);
  // переход на следующую строку
  <sql_query.Next(handle)>
end
// освобождение хендля
free_sql_query (handle);
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39751902
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петр,

Пусть указатель на объект TDataset и будет handle.
Заменить sql_query.EOF на функцию sql_query_EOF, sql_query.Next на функцию sql_query.Next, и всё - можно все остальное так и оставить.
А еще можно - объединить их в одну функцию sql_query_fetch.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39751965
Петр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да но как мне правильно объявить этот указатель в DLL, чтобы он был виден во внешнем приложении?
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39751975
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петр,

импортируй из dll интерфейс. У меня, например, такой интерфейс реализует метод GetNewQuey:
Код: pascal
1.
2.
    function GetNewQuery(aTransactionKind: TCommonTransactionKind = trcRead):
      ICommonQuery;


Где ICommonQuery выглядит (примерно) так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
ICommonQuery = interface(IUnknown)


    procedure Close;
    procedure ExecQuery;
    procedure ExecProc;
    function FieldByName(const AFieldName: string): ICommonField;
    function FN(const AFieldName: string): ICommonField;
    function ParamByName(const AParamName: string): ICommonField;
    function FieldCount: Integer;
    function GetFields(Index: Integer): ICommonField;
    function GetParameters(Index: Integer): ICommonField;
    function GetSQLText: string;
    function EOF: Boolean;
    function FieldExist(const aFieldName: string; var aIdx: Integer): Boolean;
    procedure Next;
    procedure Prepare;
    function RecordCount: Integer;
    procedure SetSQLText(const Value: string);
    procedure SQLAdd(aItem: string);
    procedure SQLClear;
    function GetTransaction: ICommonTransaction;
    procedure SetTransaction(const Value: ICommonTransaction);
    property Fields[Index: Integer]: ICommonField read GetFields;
    property Parameters[Index: Integer]: ICommonField read GetParameters;
    property SQLText: string read GetSQLText write SetSQLText;
    property Transaction: ICommonTransaction read GetTransaction write
      SetTransaction;
  end;



Реализация - в соответствии с внутренними особенностями используемых компонентов.

Использование (например, заполнение массива aReports):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
procedure GetListReports(var aReports: TReports);
var
  fqGet: ICommonQuery;
begin
  SetLength(aReports, 0);
  fqGet := ConnectDataModule.GetNewQuery();
  fqGet.SQLAdd('select r.Report_id, r.Report_Type, r.Name ');
  fqGet.SQLAdd(' from Reports r order by r.Name');
  fqGet.ExecQuery;
  while not fqGet.Eof do
  begin
    SetLength(aReports, length(aReports) + 1);
    aReports[High(aReports)].id := fqGet.FieldByName('Report_id').AsInteger;
    aReports[High(aReports)].RepType := fqGet.FieldByName('Report_Type').AsString;
    aReports[High(aReports)].RepName := fqGet.FieldByName('Name').AsString;
    fqGet.Next
  end;
end;



Здесь ConnectDataModule - "корневой" интерфейс, импортированный из dll.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752003
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петрда но как мне правильно объявить этот указатель в DLL, чтобы он был виден во внешнем приложении?Никак не объявить. Его будет возвращать ф-ция set_sql_query.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752305
Петр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockПетрда но как мне правильно объявить этот указатель в DLL, чтобы он был виден во внешнем приложении?Никак не объявить. Его будет возвращать ф-ция set_sql_query.

что-то не работает:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
var
  ADOQuery: TADOQuery;
***
function open_query(SQL: PWideChar; var ErrMessage: PWideChar): Pointer stdcall;
begin
 try
  ADOQuery := TADOQuery.Create(nil);

  if not ADOConnection.Connected then
   begin
     ErrMessage := 'Connection not exists (open_query)';
     exit;
   end;

  ADOQuery.Connection := ADOConnection;
  ADOQuery.SQL.Text := SQL;

  ADOQuery.Open;
  ADOQuery.First;
  //result := Integer(Addr(ADOQuery));
  result := Addr(ADOQuery);
 except
   on e: Exception do ErrMessage := PWideChar(E.Message);
 end;
end;

function get_value_int(aADOQuery: Pointer; ColIndex: integer; var ErrMessage: PWideChar):integer stdcall;
begin
 result := -1;
 try
  if not ADOConnection.Connected then
   begin
     ErrMessage := 'Connection not exists (get_value_int)';
     exit;
   end;

  if not TADOQuery(aADOQuery).Active then
   begin
     ErrMessage := 'Query not open (get_value_int)';
     exit;
   end;

  result := TADOQuery(aADOQuery).Fields[ColIndex].AsInteger;

  if not TADOQuery(aADOQuery).Eof then TADOQuery(aADOQuery).Next;
 except
   on e: Exception do ErrMessage := PWideChar(E.Message);
 end;
end;
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752311
Петр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фэйтл ЭраПетр,

импортируй из dll интерфейс. У меня, например, такой интерфейс реализует метод GetNewQuey:
Код: pascal
1.
2.
    function GetNewQuery(aTransactionKind: TCommonTransactionKind = trcRead):
      ICommonQuery;


т.е. вы возвращаете сразу массив?
не работал никогда в "интерфейсом", в данном случае почему именно он используется?
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752338
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петр,

тебе надо разобраться, что такое интерфейс.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752349
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петрчто-то не работаетт.к. очень много ошибок.
1. Addr не нужен, просто приводи к типу. А то получается указатель на указатель, который ты потом не разадресовываешь.
2. Что за ADOConnection, кто его создает - неизвестно.
3. Твой ErrMessage - это ад какой-то. Ты туда мертвый указатель посылаешь зачастую.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752353
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петр,

Зачем это все надо? Для общего развития?
Удобно так не будет. Пусть dll лучше возвращает результат, а не буффер из базы данных.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752383
Петр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockПетрчто-то не работаетт.к. очень много ошибок.
1. Addr не нужен, просто приводи к типу. А то получается указатель на указатель, который ты потом не разадресовываешь.
2. Что за ADOConnection, кто его создает - неизвестно.
3. Твой ErrMessage - это ад какой-то. Ты туда мертвый указатель посылаешь зачастую.

ошибок не дает, но значение поля не возвращает.

1. подскажите как правильно, не селен в указателях
2. не весь код прислал. ADOConnection - устанавливает коннект с БД
3. ErrMessage - это не важно

зачем надо:

надо чтобы из другой программы (язык MQL4) получить последовательность записей запроса Query (select * from table)
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752384
Петр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
могу привести весь код если надо для теста
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752385
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петр,
1. Для начала передаешь widestring, а не PWidechar. Pwidechar - ссылкается на string, который может в любое время уничтожиться.
2. Result := Pointer(ADOQuery);
3. Помни про общий менеджер памяти.
4. Сделай все на интерфейсах+widestring, так жить проще. Интерфейсы - это классы, только лучше :)
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752387
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петр,
1. Ничего не делай в секциях initialization и finalization - ибо грех это.
2. Multithreaded = true - это тоже важно.
3. CoInitializate - надо наверное тоже сделать, и обратную процедуру не забыть.
В чем ошибка-то?
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752389
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петр,
Для начала научись передавать просто текст из mql4 в приложение. А потом займись уже Ado.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752405
Петр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
итак вроде что-то вырисовывается:
Код в принципе заработал. Первый затык был
Код: pascal
1.
result := TADOQuery(aADOQuery).Fields[ColIndex].AsInteger;


по индексу значение не выдавалось, заменил на
Код: pascal
1.
result := TADOQuery(aADOQuery).FieldByName(FieldName).AsInteger;



тип PWideChar - был выбран не случайно с widestring не работает.

значения integer DLL возвращает правильно, символьные возвращает в виде: '??' - похоже в кодировке проблема

главный вопрос именно в правильном объявлении TADOQuery - где и как объявлять?

на данный момент:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
function open_query(SQL: PWideChar; var ErrMessage: PWideChar): Pointer stdcall;
begin
 try
  ADOQuery := TADOQuery.Create(nil);

  if not ADOConnection.Connected then
   begin
     ErrMessage := 'Connection not exists (open_query)';
     exit;
   end;

  ADOQuery.Connection := ADOConnection;
  ADOQuery.SQL.Text := SQL;

  ADOQuery.Open;
  ADOQuery.First;
  //result := Integer(Addr(ADOQuery));
  result := Pointer(ADOQuery);
 except
   on e: Exception do ErrMessage := PWideChar(E.Message);
 end;
end;

function get_value_int(aADOQuery: Pointer; FieldName: PWideChar; var ErrMessage: PWideChar):integer stdcall;
begin
 result := -1;
 ErrMessage := 'OK';
 try
  if not ADOConnection.Connected then
   begin
     ErrMessage := 'Connection not exists (get_value_int)';
     exit;
   end;

  if not TADOQuery(aADOQuery).Active then
   begin
     ErrMessage := 'Query not open (get_value_int)';
     exit;
   end;

  result := TADOQuery(aADOQuery).FieldByName(FieldName).AsInteger;

  if not TADOQuery(aADOQuery).Eof then TADOQuery(aADOQuery).Next;
 except
   on e: Exception do ErrMessage := PWideChar(E.Message);
 end;
end;
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752407
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петр,

передача объекта по ссылке из dll чрезвычайно опасна. Даже изменение опций того же самого компилятора может повлечь трудноуловимые глюки.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752410
Петр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фэйтл ЭраПетр,

передача объекта по ссылке из dll чрезвычайно опасна. Даже изменение опций того же самого компилятора может повлечь трудноуловимые глюки.

возможно, как тогда решить задачу? Возвращением массива? Хотя тут я тоже не уверен, что получиться его правильно вернуть...
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752413
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петрвозможно, как тогда решить задачу?Мы откуда знаем. Ты ж условие задачи не говоришь.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752415
Петр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockПетрвозможно, как тогда решить задачу?Мы откуда знаем. Ты ж условие задачи не говоришь.

дважды сказал:
2-я строка первого поста:
Есть внешнее приложение в котором нужно вернуть последовательно строки датасета, для последующей обработки.

и ниже по тексту:
зачем надо:

надо чтобы из другой программы (язык MQL4) получить последовательность записей запроса Query (select * from table)
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752510
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петр надо чтобы из другой программы (язык MQL4) В нем точно можно dll подключать?
Если да - то что-то вроде 1-го твоего поста. Но только надо изучить, как работать с памятью и все остальное.
Как передавать во внешнюю прогу строки и прочее. Буфферы для этого должны быть выделены там,
а значит - сначала надо их подготовить, а лишь затем - фетчить записи.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752518
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Петр надо чтобы из другой программы (язык MQL4) получить последовательность записей запроса Query (select * from table)
Что ж ты сразу не сказал про мкл4.

Фиг тебе, а не интерфейсы.
И, естественно, никаких тебе объектов из dll.
Используй какую-нибудь json или xml или csv для возврата структур. Проще всего возвращать все записи сразу. Ибо иначе тебе придется в длл готовить и хранить контекст запроса. Ничего сложного, просто кодить больше.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752520
Фотография Gator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фэйтл ЭраИ, естественно, никаких тебе объектов из dll.Стесняюсь спросить, тебе религия мешает?
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752524
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GatorФэйтл ЭраИ, естественно, никаких тебе объектов из dll.Стесняюсь спросить, тебе религия мешает?
Ну расскажи скорее, как объекты Delphi в MQL4 использовать.
...
Рейтинг: 0 / 0
обращение к DataSet через dll
    #39752531
Фотография Gator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фэйтл Эра,
Алрес, он и в Африке - адрес. На что он указывает и когда - тебе знать надо (область видимости). Адреc обеспечиваешь ты, как и структуру по этому адресу. Главное, вовремя данные обеспечить и память освободить
...
Рейтинг: 0 / 0
25 сообщений из 37, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / обращение к DataSet через dll
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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