Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Помогите начинающему!!!


Alex222 ©   (2006-01-21 20:52:00) 

Подключил DLL, в основном все получается, но не могу вызвать одну процедуру. В прототипе
procedure SyncRead( var Serv: PSafeArray); safecall;

Как мне правильно завести переменную Serv чтобы не ругался компилятор на несовпадение типов. Эта программа работает в VisualBasic там эта переменная объявлена как массив string


Alex222   (2006-01-26 19:39:00) [1]

Так все работает:
use  ... ActiveX;
var  Serv: PSafeArray;
    i,ix:integer;
    rgsabound: array[0..1] of TSafeArrayBound;
    MyServer : TPCServer;
Begin
if not Assigned(MyServer) then
  MyServer := TPCServer.Create(MyPCServer);
// 1-й вариант:
  Serv:= TVarData(VarArrayCreate([1,5],varDouble)).VPointer;
// 2-й вариант:
  rgsabound[0].lLbound:=1;
  rgsabound[0].cElements:=5;
   Serv:=SafeArrayCreate(VT_r8,1,rgsabound);
//  Общее:
    i:=1;ix:=33;
    SafeArrayPutElement(Serv,i,ix);
    xx.SyncWrite(1,Serv);
    SafeArrayGetElement(Serv,i,ix);
    edit1.Text:=inttostr(ix);

А теперь вопрос: как мне подключить обработчик события MyServer
На форме значка нет, чтобы на нем щелкнуть,класс взят из DLL
Заранее всем благодарен.


Набережных С.   (2006-01-22 19:47:00) [2]

Можно и так:

TVarData(Result).VType:= varArray or varOleStr;
TVarData(Result).VAny:= err;

но с учетом типа елементов в Err. Или вместо

err:=  TVarData(VarArrayCreate([0, Pred(1)], varDouble)).VPointer;

написать так:

Result:=  VarArrayCreate([0, Pred(1)], varDouble);
err:= TVarData(Result).VPointer


tesseract   (2006-01-22 19:06:00) [3]


> теперь осталось научиться   читать и писать в такой хитрый
> массив


А зачем? Передавай все строки в WideString с разделителями строк например #13#10.
Потом рассортируешь.


> Это ты мне что-ли объясняешь?:) Забавно:)))


Ну надо же повыёживаться :-)


sniknik   (2006-01-22 18:57:00) [4]

> теперь осталось научиться   читать и писать в такой хитрый массив
SafeArrayGetElement
SafeArrayPutElement


Набережных С.   (2006-01-22 17:03:00) [5]


> tesseract ©   (22.01.06 16:22) [11]

Это ты мне что-ли объясняешь?:) Забавно:)))


Alex222   (2006-01-22 16:26:00) [6]

Подключил в uses  ActiveX
var    Serv,Val,Err: PSafeArray;
      Result:Variant;
begin serv:= TVarData(VarArrayCreate([0, Pred(1)], varDouble)).VPointer;
     val:= TVarData(VarArrayCreate([0, Pred(1)], varVariant)).VPointer;
     err:=  TVarData(VarArrayCreate([0, Pred(1)], varDouble)).VPointer;
 MyOPCGroup.SyncWrite(1,Serv,Val,Err);

TVarData(Result).VAny:= err;
edit1.Text:=Result[1];       -  Дает ошибку Invalid argument при выполнении
теперь осталось научиться   читать и писать в такой хитрый массив


tesseract   (2006-01-22 16:22:00) [7]


> SafeCall - оно и есть StdCall, само по себе. Вот только
> странность - SafeCall имеет смысл только в COM, а тут вроде
> как речь об обычной ДЛЛ. Непонятно

SafeCall к Com и относится отличается от StdCAll допзащитой межпроцессного взаимодействия.  
Cdecl отличается тем что чистить память должен вызывающий роцедуру, а stdCall - вызываемая процедура.


> размерность массива и что данные типа string

Данные типа string - разные всё таки скажи что-ты используешь?????
Com или Dll


Набережных С.   (2006-01-22 16:06:00) [8]


> sniknik ©   (22.01.06 13:19) [8]

А, ну да, дошло наконец-то:)))


Набережных С.   (2006-01-22 15:28:00) [9]


> а она компилится раз ругается у тебя на не совпадения типов.
> .. иначе бы еще раньше ругалось бы "Undeclared identifier"


> sniknik ©   (22.01.06 13:19) [8]


> Alex222   (22.01.06 11:50) [5]


> А он мне пишет  Undeclared identifier: 'PSafeArray'

?


sniknik   (2006-01-22 13:19:00) [10]

> а если бы я не знал этого то как можно было бы узнать??
посмотреть в том модуле откуда эта декларация (*_TLB ?), если она компилится то все используемые модули в ней указаны (а она компилится раз ругается у тебяна не совпадения типов... иначе бы еще раньше ругалось бы "Undeclared identifier").

p.s. зажми Ctrl и кликни мышкой на этом типе (только из того модуля что компилится, не из своего)... в какой модуль попал? его и себе подключай.


Набережных С.   (2006-01-22 13:18:00) [11]


> А он мне пишет  Undeclared identifier: 'PSafeArray'
> может надо подключить что-то в поле uses ???

Разумеется, нужно. А что именно - на то в среде поиск по файлам есть.


Набережных С.   (2006-01-22 13:17:00) [12]


> tesseract ©   (21.01.06 22:12) [3]


> ;stdcall;safecall;

SafeCall - оно и есть StdCall, само по себе. Вот только странность - SafeCall имеет смысл только в COM, а тут вроде как речь об обычной ДЛЛ. Непонятно.

> Alex222   (22.01.06 11:50) [5]

Попробуй вот это, один из вариантов должен подойти:

function InvokeSyncRead1(ItemCount: integer): OleVariant;
var
 pArr: PSafeArray;
begin
 Result:= VarArrayCreate([0, Pred(ItemCount)], varOleStr);
 pArr:= TVarData(Result).VAny;
 SyncRead(pArr);
end;

function InvokeSyncRead2(ItemCount: integer): OleVariant;
var
 pArr: PSafeArray;
begin
 Result:= VarArrayCreate([0, Pred(ItemCount)], varOleStr);
 pArr:= TVarData(Result).VPointer;
 TVarData(Result).VAny:= nil;
 SyncRead(pArr);
 TVarData(Result).VAny:= pArr;
end;

Скорее всего первый, но проверь, если до и после вызова значение SyncRead pArr одинаково, то используй первый вариант, если pArr изменяется внутри SyncRead, то второй.


Alex222   (2006-01-22 11:50:00) [13]

А он мне пишет  Undeclared identifier: 'PSafeArray'
может надо подключить что-то в поле uses ???
и потом, массив мне не надо заполняь, его заполнит
вызываемая процедура, нужно только указать
размерность массива и что данные типа string.
а если бы я не знал этого то как можно было бы узнать??


GuAV   (2006-01-21 22:27:00) [14]

var Serv: PSafeArray;
begin
 Serv := PSafeArray(VarArrayAsPSafeArray(
   VarArrayOf(['Первый', 'Второй', 'Третий'])));
 SyncRead(Serv);
end;


tesseract   (2006-01-21 22:12:00) [15]

ммммм.......
Насчёт васика не уверен - но в принципе он должен использовать stdcall.
в процедуре докатай ;stdcall;safecall;

Передача данных через указатель - must be known. Ты же с winApi так общаешься.

А зачем тебе с васиком общаться? Имей в виду pascal string, Basic string и PChar - вещи очень разные.


ALex222   (2006-01-21 21:14:00) [16]

Если можно, поподробннее какую конкретно строчку ввести после var и после Begin


tesseract   (2006-01-21 20:56:00) [17]

Как обычно - через pointer. И к процедуре лучше, наверно, дописать StdCall.
Да и размер массива вернуть не помешает.


Наверх

Титульная страница Поиск, карта сайта Написать письмо