Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.12;
Скачать: CL | DM;

Вниз

Помогите начинающему!!!   Найти похожие ветки 

 
Alex222   (2006-01-21 20:52) [0]

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

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


 
tesseract ©   (2006-01-21 20:56) [1]

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


 
ALex222   (2006-01-21 21:14) [2]

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


 
tesseract ©   (2006-01-21 22:12) [3]

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

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

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


 
GuAV ©   (2006-01-21 22:27) [4]

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


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

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


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


> 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, то второй.


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


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

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


 
sniknik ©   (2006-01-22 13:19) [8]

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

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


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


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


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


> Alex222   (22.01.06 11:50) [5]


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

?


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


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

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


 
tesseract ©   (2006-01-22 16:22) [11]


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

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


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

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


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

Подключил в 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 при выполнении
теперь осталось научиться   читать и писать в такой хитрый массив


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


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

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


 
sniknik ©   (2006-01-22 18:57) [14]

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


 
tesseract ©   (2006-01-22 19:06) [15]


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


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


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


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


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

Можно и так:

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


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

Так все работает:
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
Заранее всем благодарен.



Страницы: 1 вся ветка

Текущий архив: 2006.02.12;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.04 c
15-1138032107
Exciter
2006-01-23 19:01
2006.02.12
Есть ли XPMan для D5 ?


15-1137658991
RDA
2006-01-19 11:23
2006.02.12
AutomatedQA.AQTime


2-1138071002
555
2006-01-24 05:50
2006.02.12
Открытие файла Word


15-1137777591
Андрей К
2006-01-20 20:19
2006.02.12
Воторое высшие


2-1138280829
Trilon1
2006-01-26 16:07
2006.02.12
EOleException