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

Вниз

выходные параметры в СОМ-сервере   Найти похожие ветки 

 
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 вся ветка

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

Наверх




Память: 0.51 MB
Время: 0.021 c
15-1183130798
linzaolog
2007-06-29 19:26
2007.07.29
аналог ListBox


2-1183640247
POP
2007-07-05 16:57
2007.07.29
64bit HEX преобразовать в DEC строку


2-1183461171
Тимофей
2007-07-03 15:12
2007.07.29
всё очень просто


2-1183357283
Aibio
2007-07-02 10:21
2007.07.29
работа с MSSQL2000


2-1183404561
ilya_ae
2007-07-02 23:29
2007.07.29
insertSql