Jump to content

Remy Lebeau

Members
  • Content Count

    2333
  • Joined

  • Last visited

  • Days Won

    94

Posts posted by Remy Lebeau


  1. I would opt to simply eliminate J altogether:

    function IndexOfFirstNotOf(const s: string; Ch: Char): Integer;
    begin
      for Result := 1 to Length(s) do begin
        if s[Result] <> Ch then Exit;
      end;
      Result := 0;
    end;
    
    function RemoveZeroLeft(const s : String) : string;
    var
      i : integer;
    begin
      i = IndexOfFirstNotOf(s, '0');
      if i > 1 then
        Result := Copy(s, 1, MaxInt)
      else if i = 1 then
        Result := s
      else
        Result := ''; // or '0' if needed
    end;

     


  2. 59 minutes ago, EugeneK said:

    What I'm saying is that Embarcadero can theoretically hide ability to implement this interface manually

    You can't manually implement the interface of an anonymous method.  It is a compiler-generated type that you can't refer to. And it doesn't have a Guid assigned to it, so you can't query for it at runtime, either.  All you can do is hold a reference to it.  The compiler generates the necessary code to call its Invoke() when it sees user code trying to call the anonymous method.  It is possible to manually call Invoke() directly (by declaring the interface manually, and then casting the anonymous method), but there is no good reason to ever do that.

    59 minutes ago, EugeneK said:

    Or they can change interface, say, rename Invoke to InvokeEx for some reason.

    They could, and that shouldn't change anything at all, because user code shouldn't ever be calling Invoke() directly to begin with.

    59 minutes ago, EugeneK said:

    So manually implementing this interface is a hack that can randomly stop working.

    Nobody is "manually implementing" the interface of an anonymous method.


  3. Depends on the context. The compiler thinks you are using J's value before you have actually assigned any value to J. Sometimes the compile makes a mistake on this, sometimes not, so it may or may not be a false positive. How are you actually using J exactly? Can you show that code? 


  4. 1 hour ago, PeterPanettone said:

    Is there a known solution to this problem?

    Unfortunately, it is not so simple.  There are many different ways for file types to be associated with an app.  The Registry keys you are currently looking at (the ones starting with a dot) is just the beginning.  Those are static verb registrations, and the most common approach.  But there are other ways, too.  Especially when you start taking into account things like dynamic registrations, Shell COM objects for File Type handlers and Context Menu handlers, etc.  A lot can go on behind the scenes when the OS is asked to open an app associated with a given file.

    • Like 2

  5. 2 hours ago, EugeneK said:

    So it is not officially supported and theoretically can be changed?

    In theory, pehaps.  In practice, not likely.

    32 minutes ago, EugeneK said:

    I think anonymous methods will still work without ability to explicitly use them as interfaces.

    Using an interface makes for easier lifetime management.  An anonymous procedure can capture variables, so they have to be stored somewhere that can follow the procedure as it's passed around.  As long as someone has a reference to the procedure, the variables have to be maintained.  So it makes sense for the implementation to use a separate object for that storage.  And someone has to create that object, and more importantly destroy that object after everyone is done using it.  Since Delphi doesn't have garbage collection, using a reference-counted interface makes sense.

    12 minutes ago, EugeneK said:

    But this implementation does not have to be accessible as interface to end user for it to work.

    How would you propose doing it without using an interface?  The only way that makes sense to me is a managed record with a manual reference count (but managed records didn't exist yet when anonymous procedures were introduced).

     

    In any case, just because an anonymous procedure is implemented using an interface does not mean you have to use it as an interface.


  6. 1 hour ago, EugeneK said:

    basically anonymous method declaration is equivalent to interface.

    That is correct. Basically, an anonymous method is implemented as an interfaced object with an Invoke() method that matches the signature of the anonymous method.

    https://stackoverflow.com/questions/39955052/how-are-anonymous-methods-implemented-under-the-hood

    1 hour ago, EugeneK said:

    Is it documented somewhere?

    Not by Embarcadero, as it is an implementation detail of the compiler.  But it is a well-known implementation that is documented on numerous sites/blogs.

    • Like 1

  7. You are invoking floating-point division, not integer division.  All floating-point exceptions have been intentionally disabled by default in Delphi 12:

     

    http://docwiki.embarcadero.com/RADStudio/Athens/en/What's_New#Disabling_Floating-Point_Exceptions_on_All_Platforms

     

    Dividing a floating-point value by 0 used to raise an EDivByZero exception, but by default it no longer does so.

     

    This page explains how to restore the old behavior if you really need it:

    http://docwiki.embarcadero.com/RADStudio/Athens/en/Floating_Point_Operation_Exception_Masks#How_to_Restore_Old_Behavior

     

    • Like 1

  8. That error message doesn't necessarily mean the specified file can't be found.  It can also mean that a DLL/BPL that the specified file depends on can't be found.  Unfortunately, Windows doesn't differentiate between those two cases.  But what you can do is use a tool like SysInternals Process Monitor to see exactly which file is not being found and where exactly Windows is looking for the file.  That may give you some better clues.


  9. 2 hours ago, mdsantos said:

    The problem now it's that the idHTTP post request is very slow to receive an response (it takes about a minute or more), using Postman it's less than a 1 sec.

    Unless you are sending a massively large JSON, or receiving a massively large JSON, then it should not be taking anywhere near that long to encode/decode the data.  So I have to assume that either 1) you are on a very slow network, or 2) the response from the server is really taking that long to transmit.  Use a packet sniffer to check that, as well as to compare the Postman traffic to the TIdHTTP traffic any differences.


  10. 3 hours ago, Adam said:

    I think in Delphi 12, the packages are named with 290 at the end of them. (At least from my memory from last week when I was deleting the BPL's), so that might have changed now? With prior versions of Delphi I think Embarcardero omitted the version number suffix. (Although again, I'm going from memory now, so take with a grain of salt).

    The packages in Indy's GitHub repo are named with version-specific suffixes on each DPK/DPROJ file.  The bundled Indy packages that ship with the IDE have been modified by Embarcadero to use LIBSUFFIX when compiled, so the version suffixes are omitted from the generated DCP files but not from the final BPL files.

    • Thanks 1

  11. 7 hours ago, msohn said:

    TSPoint only contains two UInt32 so AFAICS it is always 8 bytes in size, regardless of packed or $A settings:

    If the record is 8-byte aligned, then it would have padding between the 2 integers. That is why I suggested you verify the record's actual size and alignment on the Delphi side.  If you need to ensure the record is 8 bytes, then applying 'packed' or ($ALIGN 4} to the record is the way to go.

    7 hours ago, msohn said:

    And to make things worse, the identical API ts_node_start_point does not return anything in EDX:EAX, i.e. when stepping over the call, both registers remain unchanged.

    You are missing the 'cdecl' calling convention on your declaration of ts_node_start_point() under 32bit, so the Delphi compiler uses the 'register' calling convention instead.


  12. On 3/7/2024 at 12:26 PM, DelphiUdIT said:

    If make a "del Id*" from batch file, only the "idoc and idispids" are interesting, from explorer all the others are presented.

     

    You can copy those files (idoc and idispids) to a backup place and restore after delete.

    I have now updated Clean_IDE.cmd to do exactly that.

    On 3/7/2024 at 12:26 PM, DelphiUdIT said:

    Others way is to delete only a list of know files.

    I might consider doing that for a future version of the .cmd script.  That would probably require making a separate .txt file of all the known Indy units and then have the .cmd script loop through that file for every platform.


  13. See:

    https://stackoverflow.com/questions/45241488/how-does-the-cdecl-calling-convention-returns-a-struct

    https://stackoverflow.com/questions/16119116/passing-record-as-a-function-result-from-delphi-dll-to-c

     

    The C code is returning the struct wholly in the EDX:EAX register, but Delphi is expecting it to be passed via a hidden reference parameter instead, according to the same Language Guide you linked to:

    Quote

    For static-array, record, and set results, if the value occupies one byte it is returned in AL; if the value occupies two bytes it is returned in AX; and if the value occupies four bytes it is returned in EAX. Otherwise, the result is returned in an additional var parameter that is passed to the function after the declared parameters.

    So, your Int64 hack is likely the only way to go for 32bit, unless you have access to change the C code to match Delphi's use of an output parameter.  Also, make sure your TPoint record in Delphi has the right size and alignment to match the C type.  You did not show your declaration of the record, but if it is not declared with 'packed' or {$ALIGN} then it may have extra padding in it, making it larger than the C type, which would explain why you are having trouble accessing the column field.


  14. 10 hours ago, DelphiUdIT said:

    What components were dropped ? I replaced totally Indy without any issue, restoring also the IDE functionalities.

    Yes, but you did that using Indy's master code, which only had bug fixes and new package files.  Try it again with branched code that has interface changes in it, and you may have a different result.


  15. 13 hours ago, Adam said:

    I was unfortunately not able to get Indy to work just by including the changed units that I needed for oAuth. It seems that the changes go deep right back to the idpop3 unit, which is pretty much integrated throughout a lot of Indy.

    More accurately, there are some interface changes to the base TIdSASL class and the TIdSASLMechanisms class, which affects several Indy components that use SASL, including TIdPOP3, TIdSMTP, TIdIMAP4, and TIdDICT.

    13 hours ago, Adam said:

    It would be good though to have SASL-oAuth officially distributed by Embarcadero in their future releases of Delphi.

    Yes, but that's not going to happen until the branch is merged into the master code.  Embarcadero doesn't ship branched code.


  16. 19 hours ago, Adam said:

    I'm not sure whether the SASL components are compatible with the version that comes with Delphi (if additional parameters are required or not).

    The new OAuth SASL classes are not compatible with the pre-bundled Indy version. The sasl-oauth branch contains some interface changes, to add an APort parameter to the SASL process.

    19 hours ago, Adam said:

    If I could just add the OAUTH/SASL, and leave everything else alone...

    Unfortunately, not.


  17. On 3/4/2024 at 11:12 AM, DelphiUdIT said:

    Now you need to go to the LIB directory and list all the ID* files of the subdirectories (use the pane at the top right of the explorer to search). I recommend listing the files by NAME.

    The list includes a series of files (more than 10000) that will need to be deleted, BUT FROM THIS LIST YOU MUST UNSELECT (i.e. THE FILES SHOULD NOT BE DELETED) the following files:

    - all files starting with "FMX", should be 16;
    - all files starting with "Vcl", should be 8;
    - all files starting with "play", should be 4;
    - the "idoc.dcu" files should be 4;
    - the "idispids.dcu" files should be 4;

    The procedure indicated in the link (Update Indy) would have deleted these last 8 files.

    When I try this step in Delphi 12, there are only 16 files TOTAL listed:

    - 8 starting with FMX

    - 8 starting with VCL

    All 8 are Indy files (and all of them are related to IdAntiFreeze), there are no "play" files, no "idoc.dcu" or "idispids.dcu" files, etc.

     

    I'm guessing the missing files are platform-specific files, in which case this step is dependent on the configuration chosen when you install the IDE.  I don't have any non-Windows platforms installed.

     

    I'll have to figure out a way to filter out the non-Indy files so they don't get auto-deleted by accident.

×