Sign in Join

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

Mailing lists / fpc-pascal / 2016-10

importtl tool

13 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

LacaK

Hi,

I have noticed, that tool for importing type library into pas incorrectly imports interface methods, which should have "var" parameter.

For example in my case imported:
    function
ScGetStringValue(Type_:Integer;Value:WideString):Integer;dispid 33;
but it should be:
    function ScGetStringValue(Type_:Integer;var
Value:WideString):Integer;dispid 33;

I think, that it is bug as far as delphi imports same type library with "var".

Has somebody similar experience?

-Laco.

José Mejuto
to LacaK
LacaK wrote 16 lines
Hi, I have noticed, that tool for importing type library into pas incorrectly imports interface methods, which should have "var" parameter. For example in my case imported: function ScGetStringValue(Type_:Integer;Value:WideString):Integer;dispid 33; but it should be: function ScGetStringValue(Type_:Integer;var Value:WideString):Integer;dispid 33; I think, that it is bug as far as delphi imports same type library with "var". Has somebody similar experience?

Hello,

I had fixed some of this bugs in:

http://bugs.freepascal.org/view.php?id=27486

And my patch was applied with small modification (as noted by Michael Van Canneyt) and I'm not sure if this modification alters the "var" inclusion in some fields.

Unfortunatly I'm not working with the TLBs anymore so I can not perform more tests. Maybe you can try to look at my patch and replace the last lines in your typelib.pas and recompile fpc tool.

LacaK
to José Mejuto

Dňa 20.10.2016 o 14:05 José Mejuto napísal(a):

Show quoted text 28 lines
El 20/10/2016 a las 11:09, LacaK escribió: > Hi, > > I have noticed, that tool for importing type library into pas > incorrectly imports interface methods, which should have "var" > parameter. > > For example in my case imported: > function > ScGetStringValue(Type_:Integer;Value:WideString):Integer;dispid 33; > but it should be: > function ScGetStringValue(Type_:Integer;var > Value:WideString):Integer;dispid 33; > > I think, that it is bug as far as delphi imports same type library with > "var". > > Has somebody similar experience? Hello, I had fixed some of this bugs in: http://bugs.freepascal.org/view.php?id=27486 And my patch was applied with small modification (as noted by Michael Van Canneyt) and I'm not sure if this modification alters the "var" inclusion in some fields.

IMO this is not my case. As I see in your patch these lines are about property setter "procedure Set_..." but I have error in "INVOKE_FUNC" branch (about line 640-650) ...
There is:

           if bParamByRef then
             case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and

(PARAMFLAG_FIN or PARAMFLAG_FOUT) of

             PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var ';
             PARAMFLAG_FOUT:sPar:='out ';
             PARAMFLAG_FIN:sPar:='var '; //constref in safecall? TBD
             end;

In my case bParamByRef = True, but wParamFlags=0 so no "var" nor "out" is added ...
(as I do no known about type libraries I fear, that any modification which fixes my case can cause problems in another cases) So I have posted bug report:
http://bugs.freepascal.org/view.php?id=30764 may be somebody experienced can fix it ...
Thanks

-Laco.

José Mejuto
to LacaK
LacaK wrote 15 lines
There is: if bParamByRef then case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and (PARAMFLAG_FIN or PARAMFLAG_FOUT) of PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var '; PARAMFLAG_FOUT:sPar:='out '; PARAMFLAG_FIN:sPar:='var '; //constref in safecall? TBD end; In my case bParamByRef = True, but wParamFlags=0 so no "var" nor "out" is added ... (as I do no known about type libraries I fear, that any modification which fixes my case can cause problems in another cases) So I have posted bug report: http://bugs.freepascal.org/view.php?id=30764 may be somebody experienced can fix it ...

Hello,

If wParaFlags is 0 then no "var" or "out" must be added (unless bug in filling wParamFlags with value) as it should be something like "constref" as "const" is not valid because it will try to perform a copy. Maybe "var" could be used :-? but it could be a problem if the called function changes the param expecting it to be discarded on return.

For native types like int and so on a const will work, but for interfaces, widestring, ... inclusion of var can crash some functions and not adding it could crash another ones.

LacaK
to José Mejuto

Dňa 20.10.2016 o 17:48 José Mejuto napísal(a):

Show quoted text 22 lines
El 20/10/2016 a las 15:20, LacaK escribió: > There is: > if bParamByRef then > case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and > (PARAMFLAG_FIN or PARAMFLAG_FOUT) of > PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var '; > PARAMFLAG_FOUT:sPar:='out '; > PARAMFLAG_FIN:sPar:='var '; //constref in safecall? TBD > end; > In my case bParamByRef = True, but wParamFlags=0 so no "var" nor "out" > is added ... > (as I do no known about type libraries I fear, that any modification > which fixes my case can cause problems in another cases) > So I have posted bug report: > http://bugs.freepascal.org/view.php?id=30764 may be somebody experienced > can fix it ... Hello, If wParaFlags is 0 then no "var" or "out" must be added (unless bug in filling wParamFlags with value)

I do not know, but I know, that:

- when I import this type library in Delphi gives in this function "var" (not only in case of WideString but also in case of integer for example) ... so I guess that there must be way how to handle it

- when I manually add in FPC "var" it works as expected (without "var" it gives runtime error about incompatible types)

- in documentation of OCX is function parameter described as "BSTR* Value" for "var WideString" resp. "long* Value" for "var integer"

- in typelib.pas is on line 631 vt=VT_PTR and sl='PWideString' ('P' is deleted on line 635) wParamFlags=0
When I add "else" part:
case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and (PARAMFLAG_FIN or PARAMFLAG_FOUT) of

               PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var ';
               PARAMFLAG_FOUT:sPar:='out ';
               PARAMFLAG_FIN:sPar:='var '; //constref in safecall? TBD

/*added*/ else sPar:='var ';

             end;

it works for me.
But I have no idea if it can negative impact other cases ?

Thanks
-Laco.

José Mejuto
to LacaK
LacaK wrote 12 lines
- in typelib.pas is on line 631 vt=VT_PTR and sl='PWideString' ('P' is deleted on line 635) wParamFlags=0 When I add "else" part: case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and (PARAMFLAG_FIN or PARAMFLAG_FOUT) of PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var '; PARAMFLAG_FOUT:sPar:='out '; PARAMFLAG_FIN:sPar:='var '; //constref in safecall? TBD /*added*/ else sPar:='var '; end; it works for me. But I have no idea if it can negative impact other cases ?

Hello,

Looking again to the code I think you are right and is the third case "PARAMFLAG_FIN" which may be wrong, it should be "constref" (IN only). Have you tried to use constref in the else case ?

LacaK
to José Mejuto

Dňa 21.10.2016 o 12:10 José Mejuto napísal(a):

Show quoted text 20 lines
El 21/10/2016 a las 12:05, LacaK escribió: > - in typelib.pas is on line 631 vt=VT_PTR and sl='PWideString' ('P' is > deleted on line 635) wParamFlags=0 > When I add "else" part: > case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and > (PARAMFLAG_FIN or PARAMFLAG_FOUT) of > PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var '; > PARAMFLAG_FOUT:sPar:='out '; > PARAMFLAG_FIN:sPar:='var '; //constref in safecall? TBD > /*added*/ else sPar:='var '; > end; > it works for me. > But I have no idea if it can negative impact other cases ? Hello, Looking again to the code I think you are right and is the third case "PARAMFLAG_FIN" which may be wrong, it should be "constref" (IN only). Have you tried to use constref in the else case ?

Yes, when I use:
else sPar := 'constref ';
Then it works for me ...

So result should be:
             case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and
(PARAMFLAG_FIN or PARAMFLAG_FOUT) of
               PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var ';
               PARAMFLAG_FOUT:sPar:='out ';
              else sPar:='constref ';
             end;
-Laco.
José Mejuto
to LacaK
LacaK wrote 7 lines
So result should be: case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and (PARAMFLAG_FIN or PARAMFLAG_FOUT) of PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var '; PARAMFLAG_FOUT:sPar:='out '; else sPar:='constref '; end;

Hello,

Maybe a big note should be added if it is fixed in that way. Or even better

               PARAMFLAG_FOUT:sPar:='out ';
               PARAMFLAG_FIN:sPar:='constref ';
              else sPar:='constref ';

To note that both "constref" are intentional.

LacaK
to José Mejuto

Dňa 21.10.2016 o 13:42 José Mejuto napísal(a):

Show quoted text 21 lines
El 21/10/2016 a las 12:32, LacaK escribió: > So result should be: > case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and > (PARAMFLAG_FIN or PARAMFLAG_FOUT) of > PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var '; > PARAMFLAG_FOUT:sPar:='out '; > else sPar:='constref '; > end; Hello, Maybe a big note should be added if it is fixed in that way. Or even better PARAMFLAG_FOUT:sPar:='out '; PARAMFLAG_FIN:sPar:='constref '; else sPar:='constref '; To note that both "constref" are intentional.

Ok I can create patch if we (you ;-)) are sure that it is okay ? -Laco.

José Mejuto
to LacaK
LacaK wrote
> To note that both "constref" are intentional. Ok I can create patch if we (you ;-)) are sure that it is okay ? -Laco.

Hello,

I'm not "sure" because if the flag does not tell us nothing (no IN, no OUT) I do not know if there is a "default behavior" except the "ByRef" flag and both "constref" and "var" are "ByRef".

Take a look in you TLB looking for a widestring that should return information, if with this code is marked as "var" everything should be ok, if it will be marked as "constref" something in the logic is wrong.

In the other hand I do not have information about how TLBs are defined, my fixes were based in experience with some TLBs that I had and that should use, and in my case fortunately I had an equivalent C API to match against.

LacaK
to José Mejuto
Show quoted text 9 lines
>> To note that both "constref" are intentional. > Ok I can create patch if we (you ;-)) are sure that it is okay ? > -Laco. I'm not "sure" because if the flag does not tell us nothing (no IN, no OUT) I do not know if there is a "default behavior" except the "ByRef" flag and both "constref" and "var" are "ByRef".

I have found:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa367051(v=vs.85).aspx "The*[in]*attribute is applied to a parameter by default when no directional parameter attribute is specified."

Take a look in you TLB looking for a widestring that should return information, if with this code is marked as "var" everything should be ok, if it will be marked as "constref" something in the logic is wrong.

? I do not understand what do you mean
When I use Microsofts OLEView to look at TLB I see only:

   long ScGetStringValue(long Type, BSTR* Value);

There is no attribute [in],[out],... specified

According to:
https://msdn.microsoft.com/en-us/library/cc237804.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms221019(v=vs.85).aspx *"PARAMFLAG_NONE: *The behavior of the parameter is not specified." I guess, that my case is PARAMFLAG_NONE so patch should look like: case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and (PARAMFLAG_FIN or PARAMFLAG_FOUT) of

               PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var ';
               PARAMFLAG_FOUT:sPar:='out ';
               *PARAMFLAG_NONE,*
               PARAMFLAG_FIN:sPar:='var '; //constref in safecall? TBD
             end;

I leave 'var ' for Delphi compatibility ...

-Laco.

José Mejuto
to LacaK
LacaK wrote 7 lines
> I'm not "sure" because if the flag does not tell us nothing (no IN, no > OUT) I do not know if there is a "default behavior" except the "ByRef" > flag and both "constref" and "var" are "ByRef". I have found: https://msdn.microsoft.com/en-us/library/windows/desktop/aa367051(v=vs.85).aspx "The*[in]*attribute is applied to a parameter by default when no directional parameter attribute is specified."

Hello,

I was not aware about that "default" so, yes you are right.

Show quoted text 7 lines
> Take a look in you TLB looking for a widestring that should return > information, if with this code is marked as "var" everything should be > ok, if it will be marked as "constref" something in the logic is wrong. ? I do not understand what do you mean When I use Microsofts OLEView to look at TLB I see only: long ScGetStringValue(long Type, BSTR* Value); There is no attribute [in],[out],... specified

I'm quite sure that using "var" in both cases is safe in 99.9% of the cases.

OLEView will not show you the "attributes", only in the IDL source.

Show quoted text 14 lines
According to: https://msdn.microsoft.com/en-us/library/cc237804.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms221019(v=vs.85).aspx *"PARAMFLAG_NONE: *The behavior of the parameter is not specified." I guess, that my case is PARAMFLAG_NONE so patch should look like: case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and (PARAMFLAG_FIN or PARAMFLAG_FOUT) of PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var '; PARAMFLAG_FOUT:sPar:='out '; *PARAMFLAG_NONE,* PARAMFLAG_FIN:sPar:='var '; //constref in safecall? TBD end; I leave 'var ' for Delphi compatibility ...

Yes.

LacaK
to José Mejuto

Dňa 24.10.2016 o 13:10 José Mejuto napísal(a):

Show quoted text 45 lines
El 24/10/2016 a las 8:17, LacaK escribió: >> I'm not "sure" because if the flag does not tell us nothing (no IN, no >> OUT) I do not know if there is a "default behavior" except the "ByRef" >> flag and both "constref" and "var" are "ByRef". > I have found: > https://msdn.microsoft.com/en-us/library/windows/desktop/aa367051(v=vs.85).aspx > > "The*[in]*attribute is applied to a parameter by default when no > directional parameter attribute is specified." Hello, I was not aware about that "default" so, yes you are right. >> Take a look in you TLB looking for a widestring that should return >> information, if with this code is marked as "var" everything should be >> ok, if it will be marked as "constref" something in the logic is wrong. > ? I do not understand what do you mean > When I use Microsofts OLEView to look at TLB I see only: > long ScGetStringValue(long Type, BSTR* Value); > There is no attribute [in],[out],... specified I'm quite sure that using "var" in both cases is safe in 99.9% of the cases. OLEView will not show you the "attributes", only in the IDL source. > According to: > https://msdn.microsoft.com/en-us/library/cc237804.aspx > https://msdn.microsoft.com/en-us/library/windows/desktop/ms221019(v=vs.85).aspx > > > *"PARAMFLAG_NONE: *The behavior of the parameter is not specified." > I guess, that my case is PARAMFLAG_NONE so patch should look like: > case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and (PARAMFLAG_FIN > or PARAMFLAG_FOUT) of > PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var '; > PARAMFLAG_FOUT:sPar:='out '; > *PARAMFLAG_NONE,* > PARAMFLAG_FIN:sPar:='var '; //constref in safecall? TBD > end; > I leave 'var ' for Delphi compatibility ... Yes.

Thank you. Patch attached. I will attach it to bug report 30764, but there is now new comment about using "constref" ... :-) -Laco.