Форум: "Corba";
Текущий архив: 2007.07.29;
Скачать: [xml.tar.bz2];
Внизвыходные параметры в СОМ-сервере Найти похожие ветки
← →
GanibalLector © (2005-12-13 16:59) [0]Сделал СОМ-сервер и отдал заказчику(1С-франчайзер).Так вот,в моем сервере есть метод Sales,который по ID выдает различные выходные данные.Тип выходных данных BSTR*.
Выглядит это так :
procedure TAlk.Sales(ID: Integer; out Code, Name, Bar, Dept, Price,
Presence, SumSales, AmountSales: WideString);
begin
Form1.Sales(ID,Code,Name,Bar,Dept,Price,Presence,SumSales,AmountSales);
end;
в Form1
procedure TForm1.Sales(Id: Integer; var Code,Name,Bar,Dept,Price,
Presence,SumSales,AmountSales:WideString);
begin
Code:= TStrings(Grid.Items[0]).Strings[Id];
Name:= Trim(TStrings(Grid.Items[1]).Strings[Id]);
Bar := TStrings(Grid.Items[2]).Strings[Id];
Dept:= TStrings(Grid.Items[3]).Strings[Id];
Price:= TStrings(Grid.Items[4]).Strings[Id];
Presence:= TStrings(Grid.Items[5]).Strings[Id];
SumSales:= TStrings(Grid.Items[6]).Strings[Id];
AmountSales:=TStrings(Grid.Items[7]).Strings[Id];
end;
Соответственно,если реализовать клиента на Delphi через позднее связывание,то выглядеть он будет так:
var Q:Variant;
I,II:Integer;
Code,Name,Bar,Dept,Price,Presence,SumSales,AmountSales:String;
begin
Q:=CreateOleObject("T2k.Alk");
try
...
for II:=0 to Q.CountSales-1 do
begin
Q.Sales(II,Code,Name,Bar,Dept,Price,Presence,SumSales,AmountSales);
StringGrid1.Cells[0,II+1]:=Code;
StringGrid1.Cells[1,II+1]:=Name;
StringGrid1.Cells[2,II+1]:=Bar;
StringGrid1.Cells[3,II+1]:=Dept;
StringGrid1.Cells[4,II+1]:=Price;
StringGrid1.Cells[5,II+1]:=Presence;
StringGrid1.Cells[6,II+1]:=SumSales;
StringGrid1.Cells[7,II+1]:=AmountSales;
end;
Данный сабж прекрасно работает(на Delphi),НО !!! если подобное реализовать на 1С,то все выходные параметры равны ПУСТОЙ СТРОКЕ.Подскажите,в чем дело. Я так понимаю,что при создании сервера я неверно указал тип выходных параметров(ведь там можно LPSTR,LPWSTR или еще чего).
Заранее спасибо!!!
← →
Digitman © (2005-12-13 17:06) [1]как минимум нарушены соглашения о вызовах.
во всех случаях они д.б. stdcall, а в ряде случаев - safecall
← →
REA (2005-12-13 17:09) [2]а как экспортируется? Может тип вызова stdcall не поставлен?
← →
sniknik © (2005-12-13 17:42) [3]попробуй еще тип сменить на VARIANT *, для 1C он "роднее".
← →
GanibalLector © (2005-12-13 19:01) [4]2 Digitman © (13.12.05 17:06) [1]
2 REA (13.12.05 17:09) [2]
Все делал автоматом(по примерам). А safecall у меня есть. Вот
type
TAlk = class(TAutoObject, IAlk)
protected
function Get_Baud: Integer; safecall;
function Get_Port: Shortint; safecall;
procedure Set_Baud(Value: Integer); safecall;
procedure Set_Port(Value: Shortint); safecall;
...
end;
2 sniknik © (13.12.05 17:42) [3]
>попробуй еще тип сменить на VARIANT *, для 1C он "роднее".
Ну хорошо,а как потом обернуть String в VARIANT *??? Как это все вызывать при позднем связывании??? Примеры реализаций есть???
← →
sniknik © (2005-12-13 21:21) [5]> Ну хорошо,а как потом обернуть String в VARIANT *???
String никак это борландовский тип, он снаружи "загнется". WideString - практически без разницы что он что вариант (вариант включает все, именно поэтому в 1С можно типы переменных как перчатки по ходу программы менять, потому как там все варианты)
> Как это все вызывать при позднем связывании??? Примеры реализаций есть???
нет нету... вернее не было, набросал вот небольшой примерчик (WideString рядом с Variant-ом видиш? а разницу?)
из TLB основной кусокITestMetds = interface(IDispatch)
["{10488099-8271-4A79-86FE-1F6DF6B1A10B}"]
function Get_ObjectName: OleVariant; safecall;
procedure Set_ObjectName(Value: OleVariant); safecall;
procedure Sales(var Code: WideString; var Name: OleVariant; var Price: OleVariant); safecall;
property ObjectName: OleVariant read Get_ObjectName write Set_ObjectName;
end;
DLL. COM сервер, сгенеренный, изменана только обработкаunit MetodsUnit;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
ComObj, ActiveX, Test1C_TLB, StdVcl, SysUtils;
type
TITestMetds = class(TAutoObject, ITestMetds)
FName: WideString;
protected
function Get_ObjectName: OleVariant; safecall;
procedure Set_ObjectName(Value: OleVariant); safecall;
procedure Sales(var Code: WideString; var Name: OleVariant; var Price: OleVariant); safecall;
end;
implementation
uses ComServ;
function TITestMetds.Get_ObjectName: OleVariant;
begin
result:= FName;
end;
procedure TITestMetds.Set_ObjectName(Value: OleVariant);
begin
FName:= Value;
end;
procedure TITestMetds.Sales(var Code: WideString; var Name: OleVariant; var Price: OleVariant); safecall;
begin
Code:= Code + IntToStr(Random(100));
Name:= Name + IntToStr(Random(100));
Price:= Price + IntToStr(Random(100));
end;
initialization
TAutoObjectFactory.Create(ComServer, TITestMetds, CLASS_TestMetds,
ciMultiInstance, tmApartment);
end.
ну и пример вызоваunit MainPrUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComObj, Grids;
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
Button3: TButton;
StringGrid1: TStringGrid;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
v1CObj: Variant;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
v1CObj:= CreateOleObject("Test1C.TestMetds");
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
v1CObj:= Null;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
v1CObj.ObjectName:= Edit1.Text;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Label1.Caption:= v1CObj.ObjectName;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
Code: WideString;
Name, Price: Variant;
i: integer;
begin
StringGrid1.Cells[0,0]:= "Code";
StringGrid1.Cells[1,0]:= "Name";
StringGrid1.Cells[2,0]:= "Price";
for i:= 1 to 5 do begin
Code:= "Code";
Name:= "Name";
Price:= "Price";
v1CObj.Sales(Code, Name, Price);
StringGrid1.Cells[0,i]:= Code;
StringGrid1.Cells[1,i]:= Name;
StringGrid1.Cells[2,i]:= Price;
end;
end;
end.
← →
GanibalLector © (2005-12-13 23:10) [6]2 sniknik © (13.12.05 21:21) [5]
Спасибо,попробую.
← →
GanibalLector © (2005-12-14 14:33) [7]2 sniknik © (13.12.05 21:21) [5]
Поменял я все на Variant*(OleVariant).Результат тот-же. НЕ РАБОТАЕТ!
Что еще посоветуете???
← →
Владислав © (2005-12-14 15:14) [8]А можно код увидеть?
← →
GanibalLector © (2005-12-15 02:08) [9]2 Владислав © (14.12.05 15:14) [8]
А какой код??? Проблема в типах(как я думаю). Хотя...вот пример:
-создаем СОМ-сервер;
-создаем метод с одним выходным параметром(строковым)
...
-в 1С пишем(к сожалению я не 1С программист):
ст=строка;
Q=СоздатьОбъект"Тут_его_имя";
Q.MyMetod(ст);
так вот,эта переменная "ст" будет пустой. Если же подобное реализовать на Delphi,то все Ок.
З.Ы. Где-то слышал,что строки в 1С это как ShortString в Delphi. Думаю,что в этом проблема!
← →
Владислав © (2005-12-15 08:34) [10]
> GanibalLector © (15.12.05 02:08) [9]
> А какой код???
А что тогда советовать??? Хотя можно погадать...
В типе Variant бывает разный BSTR.
Есть такой:
// * BSTR VT_BSTR
И есть такой:
// * BSTR * VT_BYREF|VT_BSTR
Разница очевидна?
Может в эту сторону посмотреть?..
← →
Владислав © (2005-12-15 08:35) [11]Еще, конечно, можно найти документацию, и сделать все без танцев и бубнов. Но "это не наш метод" ;)
← →
GanibalLector © (2005-12-15 13:00) [12]Так у меня и так BSTR *.
>можно найти документацию, и сделать все без танцев и бубнов. Но "это не наш метод"
Какую??? Дайте ссылку,что-ли. Я не встречал оной.
← →
GanibalLector © (2005-12-15 14:06) [13]Вопрос снят! Разобрались с франчайзерами ;) Все работает ))
← →
umbra © (2005-12-15 14:07) [14]Язык 1С, как я понимаю - это русский клон VBA. А там параметры передаются по значению. Может в
Sales
надо параметры по ссылке передавать (с аналогом спецификатора byref из VBA)?
Страницы: 1 вся ветка
Форум: "Corba";
Текущий архив: 2007.07.29;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.041 c