[fpc-devel] Bug in passing WideString parameters to dispinterface function ?

LacaK lacak at zoznam.sk
Wed Oct 26 12:17:21 CEST 2016


FYI: Reported as bug #30792

> 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 please at this. I 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  -  fpc-devel at lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
>



More information about the fpc-devel mailing list