Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2016-10

Bug in passing WideString parameters to dispinterface function ?

3 messages · 1 person · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

LacaK

Hi,

look have imported OCX type library which result in pascal unit with "dispinterface" defined like this:

_DSamlight_client_ctrl_ocx = dispinterface
['{05D31AA6-1306-4DA0-9AE2-A8771FF6FA94}']
...

    function ScChangeTextByName(const EntityName:WideString; const

Text_:WideString):Integer;dispid 3;
...

In my program I have another method which takes AnsiString parameters:
    function TSamLightClient.ChangeTextByName(const Name, Text_:
AnsiString): boolean;
In this method I do nothing except, that I call COM object interface:
    Result := FSamLightClientCtrl.ScChangeTextByName(Name, Text_)=1;

All seems to work, but OCX behaves like Name and Text_ params are equal!

When I look at assembler:

VyrobaLaser.pas:324 Result :=
FSamLightClientCtrl.ScChangeTextByName(Name, Text_)=1; 0042A986 bac8e15b00 mov $0x5be1c8,%edx 0042A98B 8d45b0 lea -0x50(%ebp),%eax 0042A98E e82d26feff call 0x40cfc0 <fpc_finalize> 0042A993 8d5da8 lea -0x58(%ebp),%ebx 0042A996 8d45a4 lea -0x5c(%ebp),%eax 0042A999 e8b2dafdff call 0x408450 <fpc_widestr_decr_ref> 0042A99E c745a400000000 movl $0x0,-0x5c(%ebp) 0042A9A5 8d55a4 lea -0x5c(%ebp),%edx 0042A9A8 8b45f8 mov -0x8(%ebp),%eax 0042A9AB e840dcfdff call 0x4085f0 <fpc_ansistr_to_widestr> 0042A9B0 8b45a4 mov -0x5c(%ebp),%eax 0042A9B3 8903 mov %eax,(%ebx) 0042A9B5 8d5da8 lea -0x58(%ebp),%ebx 0042A9B8 83c304 add $0x4,%ebx 0042A9BB 8d45a4 lea -0x5c(%ebp),%eax 0042A9BE e88ddafdff call 0x408450 <fpc_widestr_decr_ref> 0042A9C3 c745a400000000 movl $0x0,-0x5c(%ebp) 0042A9CA 8d55a4 lea -0x5c(%ebp),%edx 0042A9CD 8b45fc mov -0x4(%ebp),%eax 0042A9D0 e81bdcfdff call 0x4085f0 <fpc_ansistr_to_widestr> 0042A9D5 8b45a4 mov -0x5c(%ebp),%eax 0042A9D8 8903 mov %eax,(%ebx) 0042A9DA 8d45a8 lea -0x58(%ebp),%eax 0042A9DD 50 push %eax
0042A9DE b920365c00 mov $0x5c3620,%ecx 0042A9E3 8d45b0 lea -0x50(%ebp),%eax 0042A9E6 8b55f4 mov -0xc(%ebp),%edx 0042A9E9 8b5204 mov 0x4(%edx),%edx 0042A9EC e8ff05feff call 0x40aff0 <fpc_dispatch_by_id> 0042A9F1 8d45b0 lea -0x50(%ebp),%eax 0042A9F4 e8b71ffeff call 0x40c9b0
<SYSTEM_assign$VARIANT$$LONGINT>
0042A9F9 83f801 cmp $0x1,%eax

It seems to me like there is used twice before <fpc_ansistr_to_widestr> is called same address:
movl $0x0,-0x5c(%ebp)
lea -0x5c(%ebp),%edx

Isn't it wrong ? (I guess that it is address of any temporary local variable used to store result of ansistr->widestr)

I can workaround this by using intermediate local variable:
   var wText: WideString;
   wText := Text_;
   Result := FSamLightClientCtrl.ScChangeTextByName(Name, wText)=1; //
use wText instead of Text_

It is so in FPC 2.6.4 in FPC 3.0.0 is assembler different, but result is still wrong.

Is it something known?

Thanks
-Laco.

Reply by email

LacaK
to LacaK

I can simplify it by this demo program (only compileable not runable):

type
   Tintf = dispinterface
     ['{05D31AA6-1306-4DA0-9AE2-A8771FF6FA94}']
     function wStr(const str1: WideString; const str2: WideString):
Integer; dispid 3;
   end;
function wStr(const str1: widestring; const str2: widestring): integer;
begin
   writeln(str1, str2);
end;
function aStr(const str1, str2: AnsiString): integer;
var intf: Tintf;
begin
   Result := wStr(str1, str2);
   // wStr in this case HERE1 and HERE2 are diferent:
   //     movl   $0x0,-0x3c(%ebp)
   //     lea    -0x3c(%ebp),%edx <--- HERE1
   //     mov    -0x8(%ebp),%eax
   //    call   0x405b50 <fpc_ansistr_to_widestr>
   // ...
   //    movl   $0x0,-0x40(%ebp)
   //    lea    -0x40(%ebp),%edx <--- HERE2
   //    mov    -0x4(%ebp),%eax
   //    call   0x405b50 <fpc_ansistr_to_widestr>
   Result := intf.wStr(str1, str2);
   // wStr in this case HERE3 are equal:
   //         movl   $0x0,-0x40(%ebp)
   //         lea -0x40(%ebp),%edx                                 <---
HERE3
   //         mov    -0x8(%ebp),%eax
   //         call   0x405b50 <fpc_ansistr_to_widestr>
   // ...
   //        movl   $0x0,-0x40(%ebp)
   //        lea -0x40(%ebp),%edx                                 <--- HERE3
   //        mov    -0x4(%ebp),%eax
   //        call   0x405b50 <fpc_ansistr_to_widestr>
end;
var
   as1, as2: AnsiString;
begin
   as1 := 'abc';
   as2 := 'def';
   aStr(as1, as2);
end.
Show quoted text 83 lines
Hi, look have imported OCX type library which result in pascal unit with "dispinterface" defined like this: _DSamlight_client_ctrl_ocx = dispinterface ['{05D31AA6-1306-4DA0-9AE2-A8771FF6FA94}'] ... function ScChangeTextByName(const EntityName:WideString; const Text_:WideString):Integer;dispid 3; ... In my program I have another method which takes AnsiString parameters: function TSamLightClient.ChangeTextByName(const Name, Text_: AnsiString): boolean; In this method I do nothing except, that I call COM object interface: Result := FSamLightClientCtrl.ScChangeTextByName(Name, Text_)=1; All seems to work, but OCX behaves like Name and Text_ params are equal! When I look at assembler: VyrobaLaser.pas:324 Result := FSamLightClientCtrl.ScChangeTextByName(Name, Text_)=1; 0042A986 bac8e15b00 mov $0x5be1c8,%edx 0042A98B 8d45b0 lea -0x50(%ebp),%eax 0042A98E e82d26feff call 0x40cfc0 <fpc_finalize> 0042A993 8d5da8 lea -0x58(%ebp),%ebx 0042A996 8d45a4 lea -0x5c(%ebp),%eax 0042A999 e8b2dafdff call 0x408450 <fpc_widestr_decr_ref> 0042A99E c745a400000000 movl $0x0,-0x5c(%ebp) 0042A9A5 8d55a4 lea -0x5c(%ebp),%edx 0042A9A8 8b45f8 mov -0x8(%ebp),%eax 0042A9AB e840dcfdff call 0x4085f0 <fpc_ansistr_to_widestr> 0042A9B0 8b45a4 mov -0x5c(%ebp),%eax 0042A9B3 8903 mov %eax,(%ebx) 0042A9B5 8d5da8 lea -0x58(%ebp),%ebx 0042A9B8 83c304 add $0x4,%ebx 0042A9BB 8d45a4 lea -0x5c(%ebp),%eax 0042A9BE e88ddafdff call 0x408450 <fpc_widestr_decr_ref> 0042A9C3 c745a400000000 movl $0x0,-0x5c(%ebp) 0042A9CA 8d55a4 lea -0x5c(%ebp),%edx 0042A9CD 8b45fc mov -0x4(%ebp),%eax 0042A9D0 e81bdcfdff call 0x4085f0 <fpc_ansistr_to_widestr> 0042A9D5 8b45a4 mov -0x5c(%ebp),%eax 0042A9D8 8903 mov %eax,(%ebx) 0042A9DA 8d45a8 lea -0x58(%ebp),%eax 0042A9DD 50 push %eax 0042A9DE b920365c00 mov $0x5c3620,%ecx 0042A9E3 8d45b0 lea -0x50(%ebp),%eax 0042A9E6 8b55f4 mov -0xc(%ebp),%edx 0042A9E9 8b5204 mov 0x4(%edx),%edx 0042A9EC e8ff05feff call 0x40aff0 <fpc_dispatch_by_id> 0042A9F1 8d45b0 lea -0x50(%ebp),%eax 0042A9F4 e8b71ffeff call 0x40c9b0 <SYSTEM_assign$VARIANT$$LONGINT> 0042A9F9 83f801 cmp $0x1,%eax It seems to me like there is used twice before <fpc_ansistr_to_widestr> is called same address: movl $0x0,-0x5c(%ebp) lea -0x5c(%ebp),%edx Isn't it wrong ? (I guess that it is address of any temporary local variable used to store result of ansistr->widestr) I can workaround this by using intermediate local variable: var wText: WideString; wText := Text_; Result := FSamLightClientCtrl.ScChangeTextByName(Name, wText)=1; // use wText instead of Text_ It is so in FPC 2.6.4 in FPC 3.0.0 is assembler different, but result is still wrong. Is it something known? Thanks -Laco.

Reply by email

LacaK
to LacaK

FYI: Reported as bug #30792

Show quoted text 138 lines
I can simplify it by this demo program (only compileable not runable): type Tintf = dispinterface ['{05D31AA6-1306-4DA0-9AE2-A8771FF6FA94}'] function wStr(const str1: WideString; const str2: WideString): Integer; dispid 3; end; function wStr(const str1: widestring; const str2: widestring): integer; begin writeln(str1, str2); end; function aStr(const str1, str2: AnsiString): integer; var intf: Tintf; begin Result := wStr(str1, str2); // wStr in this case HERE1 and HERE2 are diferent: // movl $0x0,-0x3c(%ebp) // lea -0x3c(%ebp),%edx <--- HERE1 // mov -0x8(%ebp),%eax // call 0x405b50 <fpc_ansistr_to_widestr> // ... // movl $0x0,-0x40(%ebp) // lea -0x40(%ebp),%edx <--- HERE2 // mov -0x4(%ebp),%eax // call 0x405b50 <fpc_ansistr_to_widestr> Result := intf.wStr(str1, str2); // wStr in this case HERE3 are equal: // movl $0x0,-0x40(%ebp) // lea -0x40(%ebp),%edx <--- HERE3 // mov -0x8(%ebp),%eax // call 0x405b50 <fpc_ansistr_to_widestr> // ... // movl $0x0,-0x40(%ebp) // lea -0x40(%ebp),%edx <--- HERE3 // mov -0x4(%ebp),%eax // call 0x405b50 <fpc_ansistr_to_widestr> end; var as1, as2: AnsiString; begin as1 := 'abc'; as2 := 'def'; aStr(as1, as2); end. > Hi, > > look have imported OCX type library which result in > pascal unit with "dispinterface" defined like this: > > _DSamlight_client_ctrl_ocx = dispinterface > ['{05D31AA6-1306-4DA0-9AE2-A8771FF6FA94}'] > ... > function ScChangeTextByName(const EntityName:WideString; const > Text_:WideString):Integer;dispid 3; > ... > > In my program I have another method which takes AnsiString parameters: > function TSamLightClient.ChangeTextByName(const Name, Text_: > AnsiString): boolean; > > In this method I do nothing except, that I call COM object interface: > Result := FSamLightClientCtrl.ScChangeTextByName(Name, Text_)=1; > > All seems to work, but OCX behaves like Name and Text_ params are equal! > > When I look at assembler: > > VyrobaLaser.pas:324 Result := > FSamLightClientCtrl.ScChangeTextByName(Name, Text_)=1; > 0042A986 bac8e15b00 mov $0x5be1c8,%edx > 0042A98B 8d45b0 lea -0x50(%ebp),%eax > 0042A98E e82d26feff call 0x40cfc0 <fpc_finalize> > 0042A993 8d5da8 lea -0x58(%ebp),%ebx > 0042A996 8d45a4 lea -0x5c(%ebp),%eax > 0042A999 e8b2dafdff call 0x408450 <fpc_widestr_decr_ref> > 0042A99E c745a400000000 movl $0x0,-0x5c(%ebp) > 0042A9A5 8d55a4 lea -0x5c(%ebp),%edx > 0042A9A8 8b45f8 mov -0x8(%ebp),%eax > 0042A9AB e840dcfdff call 0x4085f0 > <fpc_ansistr_to_widestr> > 0042A9B0 8b45a4 mov -0x5c(%ebp),%eax > 0042A9B3 8903 mov %eax,(%ebx) > 0042A9B5 8d5da8 lea -0x58(%ebp),%ebx > 0042A9B8 83c304 add $0x4,%ebx > 0042A9BB 8d45a4 lea -0x5c(%ebp),%eax > 0042A9BE e88ddafdff call 0x408450 <fpc_widestr_decr_ref> > 0042A9C3 c745a400000000 movl $0x0,-0x5c(%ebp) > 0042A9CA 8d55a4 lea -0x5c(%ebp),%edx > 0042A9CD 8b45fc mov -0x4(%ebp),%eax > 0042A9D0 e81bdcfdff call 0x4085f0 > <fpc_ansistr_to_widestr> > 0042A9D5 8b45a4 mov -0x5c(%ebp),%eax > 0042A9D8 8903 mov %eax,(%ebx) > 0042A9DA 8d45a8 lea -0x58(%ebp),%eax > 0042A9DD 50 push %eax > 0042A9DE b920365c00 mov $0x5c3620,%ecx > 0042A9E3 8d45b0 lea -0x50(%ebp),%eax > 0042A9E6 8b55f4 mov -0xc(%ebp),%edx > 0042A9E9 8b5204 mov 0x4(%edx),%edx > 0042A9EC e8ff05feff call 0x40aff0 <fpc_dispatch_by_id> > 0042A9F1 8d45b0 lea -0x50(%ebp),%eax > 0042A9F4 e8b71ffeff call 0x40c9b0 > <SYSTEM_assign$VARIANT$$LONGINT> > 0042A9F9 83f801 cmp $0x1,%eax > > It seems to me like there is used twice before > <fpc_ansistr_to_widestr> is called same address: > movl $0x0,-0x5c(%ebp) > lea -0x5c(%ebp),%edx > > Isn't it wrong ? (I guess that it is address of any temporary local > variable used to store result of ansistr->widestr) > > I can workaround this by using intermediate local variable: > var wText: WideString; > wText := Text_; > Result := FSamLightClientCtrl.ScChangeTextByName(Name, wText)=1; // > use wText instead of Text_ > > It is so in FPC 2.6.4 in FPC 3.0.0 is assembler different, but result > is still wrong. > > Is it something known? > > Thanks > -Laco. > _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email