Recent

Author Topic: [SOLVED] Windows: LResultFromObject call crashes with the LCL and not with FPC  (Read 7100 times)

ChrisF

  • Hero Member
  • *****
  • Posts: 542
I'm probably stupid but...

I can't call the LresultFromObject function (from the windows system dll 'oleacc.dll') within Lazarus. Any kind of call provokes always a SIGSEGV.

The same call with the same parameters is OK with FPC (and also with Delphi 7).

Trying to play with the "mode" or within any declaration for the parameters doesn't change the results: always KO with the LCL, and always OK with FPC.

Using my own LCL "alternative" gives also a correct result: so the problem is really concerning the LCL.


Here is a simple test code for a demonstration (parameters don't have any signification for this test).

LCL version (a form with a pushbutton and a statictext controls):
Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}
//{$mode delphi}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    StaticText1: TStaticText;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

type
  WPARAMM = NativeUInt;
  HRESULTT = NativeUInt;
//  WPARAMM = Longword;
//  HRESULTT = Longword;

function LResultFromObject(riid: Pointer; wParam: WPARAMM; pAcc: Pointer): HRESULTT; stdcall; external 'oleacc.dll' name 'LresultFromObject';

procedure TForm1.Button1Click(Sender: TObject);
var aWParam: WPARAMM;
var aResult: HRESULTT;
var aArray: array [0..pred(256)] of Byte;
var ppp: Pointer;
begin
  awParam:=0;
  FillChar(aArray,Sizeof(aArray),0);
  ppp:=@aArray;

  aResult := LResultFromObject(ppp, aWParam, @aArray);

  StaticText1.Caption := 'Result='+IntToStr(aResult);
end;

end.

Same code for an FPC program:
Code: [Select]
program project1;

{$mode objfpc}{$H+}
//{$mode delphi}

type
  WPARAMM = NativeUInt;
  HRESULTT = NativeUInt;
//  WPARAMM = Longword;
//  HRESULTT = Longword;

function LResultFromObject(riid: Pointer; wParam: WPARAMM; pAcc: Pointer): HRESULTT; stdcall; external 'oleacc.dll' name 'LresultFromObject';

var aWParam: WPARAMM;
var aResult: HRESULTT;
var aArray: array [0..pred(256)] of Byte;
var ppp: Pointer;
var sResult: String;

begin
  awParam:=0;
  FillChar(aArray,Sizeof(aArray),0);
  ppp:=@aArray;

  aResult := LResultFromObject(ppp, aWParam, @aArray);

  str(aResult, sResult);
  WriteLn('Result='+sResult);
end.


Does anybody see a good reason to explain the crash with the LCL, and especially the difference(s) when FPC only is used in this case ?  Currently, I'm stuck...
« Last Edit: August 30, 2014, 10:52:20 pm by ChrisF »

Never

  • Sr. Member
  • ****
  • Posts: 409
  • OS:Win7 64bit / Lazarus 1.4
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #1 on: August 29, 2014, 09:52:00 pm »
hello are you sure about your header translation?
function LresultFromObject(riid: TGUID; wParam: WPARAM; pUnk: IUnknown):LRESULT; stdcall;
found this googling
Νέπε Λάζαρε λάγγεψων οξωκά ο φίλοσ'ς αραεύσε

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #2 on: August 29, 2014, 10:43:22 pm »
Yes, I do.

The "real" API is, as you've spotted, indeed: 
LresultFromObject: function (const riid: TGUID; wParam: WPARAM; punk: IUnknown): LRESULT; stdcall;

And this is the one I'm using in my "real" code; which of course gives exactly the same result, i.e. a SIGSEGV.

My test code is just a simplification to illustrate the problem. I've forced the parameters type to the corresponding basic ones, just to be sure that there is no problem inside the LCL concerning any declaration type or any type conversion. This way I'm sure to know exactly what kind of parameters are passed to the DLL function.

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #3 on: August 29, 2014, 11:03:58 pm »
This works for me in an LCL app:

Code: [Select]
function LResultFromObject(riid: TGUID; awParam: WPARAM; pAcc: IUnknown): LRESULT; stdcall; external 'oleacc.dll' name 'LresultFromObject';
var
  aWParam: WPARAM;
  aResult: LRESULT;
  sResult: String;
  aGUID: TGUID;
  aUnk: IUnknown;

procedure TestIt;
begin
  awParam:=0;
  FillChar(aGUID,Sizeof(aGUID),0);
  try
    aResult := LResultFromObject(aGUID, aWParam, aUnk);
    str(aResult, sResult);
    WriteLn('Result='+sResult,' [',IntToHex(aResult,8),']');
  except
    writeln('Fail');
  end;
end;

Ouput:
Code: [Select]
Result=-2147024809 [80070057]

Using fpc 2.6.4. Lazarus 1.3.

Bart

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #4 on: August 29, 2014, 11:24:55 pm »
Thanks ! It does the trick.

Apparently, IUnknown has something "special" inside the LCL: casting the third parameter was the solution.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #5 on: August 30, 2014, 01:16:11 pm »
IUnknown is "constref" which forces an indirection, leaving the ordinary "const" to only signify non-modification.

Quote
         function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};

FPC_HAS_CONSTREF afaik is true for 2.6.x+

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #6 on: August 30, 2014, 03:51:12 pm »
@marcov

I'm absolutely not familiar with the COM interface, so it can explain a lot of things, but...

I can't see why it could explain the difference between the pure FPC program (i.e. LCL not involved) and the "LCL" one, concerning my test programs.

I've already noticed that constref is used in the Queryinterface, and that's how I've defined it in my own Interface.

The explanation of my very first problem in my "real" program was given in the first line of my first post:
Quote
I'm probably stupid but...

I was stupidly trying to pass a pointer on a pointer as a parameter, not the pointer itself.


But I muss confess that I'm now puzzled with the differences (i.e. pure FPC or LCL) concerning my test programs...

Never

  • Sr. Member
  • ****
  • Posts: 409
  • OS:Win7 64bit / Lazarus 1.4
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #7 on: August 30, 2014, 05:59:37 pm »
Because you get a result using a hack does not mean that your result is corect i bet is wrong the result you got in your FPC program using 2 pointers  insted of

function LresultFromObject(riid: TGUID; wParam: WPARAM; pUnk: IUnknown):LRESULT; stdcall;

when you enter a new world you have to speak the language provided to ensure your safety there , otherwise you are on your own.
Νέπε Λάζαρε λάγγεψων οξωκά ο φίλοσ'ς αραεύσε

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #8 on: August 30, 2014, 06:51:18 pm »
Code: [Select]
program project1;

{$mode objfpc}{$H+}
//{$mode delphi}

uses
  Windows;

type
  WPARAMM = NativeUInt;
  HRESULTT = NativeUInt;
//  WPARAMM = Longword;
//  HRESULTT = Longword;

function LResultFromObject(riid: Pointer; wParam: WPARAMM; pAcc: Pointer): HRESULTT; stdcall; external 'oleacc.dll' name 'LresultFromObject';
function L2resultFromObject(riid: TGUID; wParam: WPARAM; pUnk: IUnknown): LRESULT; stdcall; external 'oleacc.dll' name 'LresultFromObject';

var aWParam: WPARAMM;
var aResult: HRESULTT;
var aArray: array [0..pred(256)] of Byte;
var ppp: Pointer;
var sResult: String;

var bWParam: WPARAM;
var bGUID: TGUID;
var bUnk: IUnknown;
var bResult: HRESULT;

begin

  awParam := 0;
  FillChar(aArray, Sizeof(aArray), 0);
  ppp := @aArray;

  aResult := LResultFromObject(ppp, aWParam, nil);
  sResult := hexStr(aResult, 2*Sizeof(NativeUInt));
  WriteLn('Result ='+sResult);

  bWParam := 0;
  FillChar(bGUID, Sizeof(bGUID), 0);

  bResult := L2ResultFromObject(bGUID, bWParam, bUnk);
  sResult := hexStr(bResult, 2*Sizeof(NativeUInt));
  WriteLn('Result2='+sResult);

end.

Result:
Code: [Select]
Result =80070057
Result2=80070057

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #9 on: August 30, 2014, 08:11:34 pm »
OK, I've found the reason of the difference.

In the LCL, the COM library has already been initialized (CoInitializeEx), while it's not the case within FPC (response = CO_E_NOTINITIALIZED).

Sending a nil IAccessible interface is always OK and will result in a E_INVALIDARG response, but once the COM library has been initialized this argument must be a valid one or a crash occurs.

Adding a CoInitializeEx call before the LResultFromObject call into the FPC program provokes also a crash if this argument is not nil (and not a "real" IAccessible interface, of course).

Never

  • Sr. Member
  • ****
  • Posts: 409
  • OS:Win7 64bit / Lazarus 1.4
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #10 on: August 30, 2014, 08:34:57 pm »
results on win7 machine 64bit using the code of the original post
Also your second hack  sResult := hexStr(aResult, 2*Sizeof(NativeUInt));
converts a negative result [error] [ http://msdn.microsoft.com/en-us/library/windows/desktop/dd318557%28v=vs.85%29.aspx ][ http://msdn.microsoft.com/en-us/library/windows/desktop/aa378137%28v=vs.85%29.aspx ] to a positive one
The function
If successful, returns a positive value that is a reference to the object.
« Last Edit: August 30, 2014, 09:12:47 pm by Never »
Νέπε Λάζαρε λάγγεψων οξωκά ο φίλοσ'ς αραεύσε

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Windows: LResultFromObject call crashes with the LCL and not with FPC
« Reply #11 on: August 30, 2014, 10:44:03 pm »
You did not expect to get a positive answer with the empty data present in my test code, did you ?

Quote
Here is a simple test code for a demonstration (parameters don't have any signification for this test).

The problem wasn't the answer, but the crash.

 

TinyPortal © 2005-2018