![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите начинающему!!!
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.
Да и размер массива вернуть не помешает.