Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
OLE сервер:
function TMP_DataInt.UniMessage(ParamIn1, ParamIn2: OleVariant): OleVariant;
begin
  Result:=UniMessageHandler(ParamIn1, ParamIn2);
end;


OLE клиент:
function TMBData.UniMessage(const Command: string; const Parameters: OleVariant): OleVariant;
begin
   Result:=DataInt.UniMessage(Command,Parameters); // <-- тут изредка падает, без возможности обработать ошибку.
end;

Как забороть Stack Overflow в клиенте на этой строке?
Какие причины могут быть?
14 авг 19, 20:13    [21949603]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 5107
rgreat,
ты случайно это не в методах отрисовки вызываешь?
15 авг 19, 07:01    [21949739]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25767
rgreat
const 

Может стоит привести к одному описанию?
15 авг 19, 07:39    [21949748]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
wadman
rgreat
const 

Может стоит привести к одному описанию?

Изначально без const было.
Это я уже пытался забороть stack overflow.
Не помогло.
15 авг 19, 11:27    [21949909]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
kealon(Ruslan),

Да, графика там может использоватся.
15 авг 19, 11:29    [21949912]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
Увеличение размера стека приводит к out of memory.

Причем передаваемые параметры не больше 100 кб суммарно.
15 авг 19, 11:31    [21949916]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25767
rgreat
Это я уже пытался забороть stack overflow.

Для обеих функций const пробовал?
15 авг 19, 11:43    [21949934]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
wadman,

Как я в type library это сделаю?
Ну и опять таки в сервере ошибки не происходит.
15 авг 19, 11:49    [21949943]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 5107
rgreat
kealon(Ruslan),

Да, графика там может использоватся.
в проце прорисовки нельзя вызвать методы COM-объектов из других потоков (соответственно и процессов)

WM_PAINT и ряд других сообщений обрабатываются во время ожидания внешней процедуры, соответственно и может получиться рекурсивный вызов с переполнением стека
15 авг 19, 17:04    [21950339]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
kealon(Ruslan)
в проце прорисовки нельзя вызвать методы COM-объектов из других потоков (соответственно и процессов)

WM_PAINT и ряд других сообщений обрабатываются во время ожидания внешней процедуры, соответственно и может получиться рекурсивный вызов с переполнением стека
Хм. Интересно.

Вроде у меня в процессе прорисовки оно не вызывается. Но гляну в эту сторону. Спасибо.
15 авг 19, 17:24    [21950367]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11154
rgreat,

А под отладчиком самого стека вызовов не видно?
15 авг 19, 18:56    [21950438]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11154
Ну и добавить что-то типа такого
function TMBData.UniMessage(const Command: string; const Parameters: OleVariant): OleVariant;
begin
  Log('Enter TMBData.UniMessage');
  Result:=DataInt.UniMessage(Command,Parameters); // <-- тут изредка падает, без возможности обработать   
  Log('Leave TMBData.UniMessage');
ошибку.
end;
и посмотреть, проблема в рекурсивном вызове TMBData.UniMessage или нет
15 авг 19, 18:59    [21950442]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
_Vasilisk_
rgreat,

А под отладчиком самого стека вызовов не видно?
Битый он какой-то.
15 авг 19, 21:51    [21950524]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
После всяких тестов добился что теперь стабильно утекает не стек а память.

Вызов происходит такого вида:

var
  Command: string;
  Buff: AnsiString;
begin
  Command:='qwerty';
  Buff:=набор байтов в 8-битной строке.
  UniMessage(Command,Buff)
end;


function TMBData.UniMessage(const Command: string; const Parameters: OleVariant): OleVariant;
begin
  Result:=DataInt.UniMessage(Command,Parameters); // <-- тут
end;


Надо как-то очищать/деинициализировать OleVariant?!
15 авг 19, 23:03    [21950567]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
И да, с поточностью все хорошо.

Поток 1, зацикливаний нет.
15 авг 19, 23:11    [21950572]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11154
rgreat
Надо как-то очищать/деинициализировать OleVariant?!
Если импорт интерфейсов правильный, а не как здесь, то не нужно. IDL описание метода покажи

Из замечаний - в OleVariant нельзя записать AnsiString и string (UnicodeString). Только WideString. Поэтому у тебя вначале происходит конвертация AnsiString -> WideString и string->WideString, а потом WideString -> OleVariant (убедится в этом можно вызвав VarType(Parameters) и получить при этом varOleStr = 8).

Т.к. все три типа являются управляемыми, то, возможно делфя забывает у кого-то уменьшить счетчик ссылок.

Попробуй сделать так
var
  Command: string;
  Buff: AnsiString;
  Cmd: OleVariant;
  Params: OleVariant;
begin
  Command:='qwerty';
  Buff:=набор байтов в 8-битной строке.
  Cmd := Command;
  Params := Buff;
  UniMessage(Cmd, Params)
end;

Ну и версию Делфи озвучь
16 авг 19, 15:18    [21951127]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
А вот так - не течет.

function TMBData.UniMessage(const Command: string; const Parameters: OleVariant): OleVariant;
var
  Buff   : OleVariant;
begin
  Buff:=Parameters;
  Result:=DataInt.UniMessage(Command,Buff);
  Buff:=Unassigned;
end;


Мдя.
16 авг 19, 15:28    [21951133]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
_Vasilisk_
Ну и версию Делфи озвучь
XE3
16 авг 19, 15:30    [21951135]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11154
rgreat
А вот так - не течет.
Давай IDL. Явный косяк импорта
rgreat
XE3
Сам на ней сижу и активно юзаю интерфейсы - полет нормальный
16 авг 19, 15:33    [21951144]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11154
_Vasilisk_
Давай IDL.
И pas описание метода интерфейса
16 авг 19, 15:34    [21951146]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
_Vasilisk_
rgreat
Надо как-то очищать/деинициализировать OleVariant?!
IDL описание метода покажи

    [id(0x0000010C)]
    HRESULT _stdcall UniMessage([in] VARIANT ParamIn1, [in] VARIANT ParamIn2, [out, retval] VARIANT* ParamOut);
16 авг 19, 15:35    [21951147]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
    function UniMessage(ParamIn1, ParamIn2: OleVariant): OleVariant; safecall;
16 авг 19, 15:35    [21951148]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11154
Не повторяется

+ testole.idl
[
  uuid(157EF74F-0CF2-4BD2-95D2-A11B394877E0),
  version(2.0),
]
library testole
{
  importlib("stdole2.tlb");

  [
    uuid(D1C67572-8795-4746-8CD4-050F9D500709),
    version(1.0),
    oleautomation,
    dual
  ]
   interface ITestOle: IDispatch
  {
    [id(0x0000010C)]
    HRESULT _stdcall UniMessage([in] VARIANT ParamIn1, [in] VARIANT ParamIn2, [out, retval] VARIANT* ParamOut);
  };

  [
    uuid(25358394-662E-432D-BAEE-C0500262498F),
    version(1.0),
  ]
  coclass TTestOle {
    [default] interface ITestOle;
  };

};

+ testole_TLB.pas
[/SRC]unit testole_TLB;

// ************************************************************************ //
// WARNING                                                                    
// -------                                                                    
// The types declared in this file were generated from data read from a       
// Type Library. If this type library is explicitly or indirectly (via        
// another type library referring to this type library) re-imported, or the   
// 'Refresh' command of the Type Library Editor activated while editing the   
// Type Library, the contents of this file will be regenerated and all        
// manual modifications will be lost.                                         
// ************************************************************************ //

// $Rev: 52393 $
// File generated on 16.08.2019 15:45:34 from Type Library described below.

// ************************************************************************  //
// Type Lib: testole.tlb (1)
// LIBID: {157EF74F-0CF2-4BD2-95D2-A11B394877E0}
// LCID: 0
// Helpfile: 
// HelpString: 
// DepndLst: 
//   (1) v2.0 stdole, (C:\Windows\SysWOW64\stdole2.tlb)
// SYS_KIND: SYS_WIN32
// Cmdline:
//   "C:\Program Files (x86)\Embarcadero\RAD Studio\10.0\bin\tlibimp.exe"  -P+ -R- "testole.tlb" -Ha- -Hs- -Hr- -O- -Yc- -Pt-
// ************************************************************************ //
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers. 
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
{$ALIGN 4}

interface

uses Winapi.Windows, System.Classes, System.Variants, System.Win.StdVCL, Vcl.Graphics, Vcl.OleServer, Winapi.ActiveX;
  

// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:        
//   Type Libraries     : LIBID_xxxx                                      
//   CoClasses          : CLASS_xxxx                                      
//   DISPInterfaces     : DIID_xxxx                                       
//   Non-DISP interfaces: IID_xxxx                                        
// *********************************************************************//
const
  // TypeLibrary Major and minor versions
  testoleMajorVersion = 2;
  testoleMinorVersion = 0;

  LIBID_testole: TGUID = '{157EF74F-0CF2-4BD2-95D2-A11B394877E0}';

  IID_ITestOle: TGUID = '{D1C67572-8795-4746-8CD4-050F9D500709}';
  CLASS_TTestOle: TGUID = '{25358394-662E-432D-BAEE-C0500262498F}';
type

// *********************************************************************//
// Forward declaration of types defined in TypeLibrary                    
// *********************************************************************//
  ITestOle = interface;
  ITestOleDisp = dispinterface;

// *********************************************************************//
// Declaration of CoClasses defined in Type Library                       
// (NOTE: Here we map each CoClass to its Default Interface)              
// *********************************************************************//
  TTestOle = ITestOle;


// *********************************************************************//
// Interface: ITestOle
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {D1C67572-8795-4746-8CD4-050F9D500709}
// *********************************************************************//
  ITestOle = interface(IDispatch)
    ['{D1C67572-8795-4746-8CD4-050F9D500709}']
    function UniMessage(ParamIn1: OleVariant; ParamIn2: OleVariant): OleVariant; safecall;
  end;

// *********************************************************************//
// DispIntf:  ITestOleDisp
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {D1C67572-8795-4746-8CD4-050F9D500709}
// *********************************************************************//
  ITestOleDisp = dispinterface
    ['{D1C67572-8795-4746-8CD4-050F9D500709}']
    function UniMessage(ParamIn1: OleVariant; ParamIn2: OleVariant): OleVariant; dispid 268;
  end;

implementation

uses System.Win.ComObj;

end.

+ server.dpr
library Server;

uses
  FastMM4,
  System.Win.ComServ, System.Win.ComObj,
  System.SysUtils, System.Variants,
  testole_tlb;

type
  TOleServerImpl = class(TAutoObject, ITestOle)
    function UniMessage(ParamIn1: OleVariant; ParamIn2: OleVariant): OleVariant; safecall;
  end;
  
{$R testole.tlb}

function TOleServerImpl.UniMessage(ParamIn1: OleVariant; ParamIn2: OleVariant): OleVariant; 
begin
  Result := Format(
    '%s, %s',
    [VarTypeAsText(VarType(ParamIn1)), VarTypeAsText(VarType(ParamIn2))]
  );
end;

exports
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer;
 
begin
  TAutoObjectFactory.Create(
    ComServer,
    TOleServerImpl,
    CLASS_TTestOle,
    ciMultiInstance,
    tmBoth
  );
end.

+ client.dpr
program Client;

{$APPTYPE CONSOLE}

uses
  FastMM4,
  System.SysUtils,
  Winapi.Activex, System.Win.ComObj,
  testole_tlb;

var
  TestSrv: ITestOle;

function UniMessage(const Command: string; const Parameters: OleVariant): OleVariant;
begin
  Result:=TestSrv.UniMessage(Command,Parameters); // <-- тут
end;

procedure Call;
var
  Command: string;
  Buff: AnsiString;
begin
  Command:='qwerty';
  Buff:='1234567890';
  UniMessage(Command,Buff);
end;

procedure Test;
var
  Li: Integer;
begin
  TestSrv := CreateComObject(CLASS_TTestOle) as ITestOle;
  for Li := 0 to Round(1E+6) - 1 do
    Call;
  TestSrv := nil;
end;

begin
  Coinitialize(nil);
  Test;
  Writeln('Passed');
  Readln;
end.


К сообщению приложен файл (TestOle.zip - 3Kb) cкачать
16 авг 19, 16:18    [21951191]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
rgreat
Member

Откуда:
Сообщений: 5216
Может быть там собака порылась в символах #0 в строке?
16 авг 19, 16:28    [21951206]     Ответить | Цитировать Сообщить модератору
 Re: OLE, Stack Overflow.  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11154
rgreat
Может быть там собака порылась в символах #0 в строке?
Нет. BSTR может содержать #0

Попробуй на моем примере воспроизвести ошибку.

Исходники сервера есть? Там импорт функции такой же?
16 авг 19, 16:35    [21951215]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить