Jump to content

David Heffernan

Members
  • Content Count

    3512
  • Joined

  • Last visited

  • Days Won

    174

Everything posted by David Heffernan

  1. David Heffernan

    The Case of Delphi Const String Parameters

    There is a well known design flaw with passing arguments to const arguments. procedure Foo(const Bar: IMyInterface); .... Foo(TMyImplementingClass.Create); As we know, Foo won't increment the reference count because Bar is const. Possible issues are the object is leaked, or released early inside Foo (e.g. if something inside takes a reference and then releases it). This should be fixed by having the compiler realise at the call site that something needs to take a reference to the interface while the function is executing, and emitting the necessary code at the call site. I've given up hope that this will ever be fixed. On the other hand, perhaps I should be pleased that Idera consider itself to be one of the hottest companies around.
  2. Use some judgement. You don't need to get rid of all booleans. Code like: SetControlsEnabled(True); SetMenusEnabled(True); SetFeaturesEnabled(True); is perfectly fine. Does it make sense when you read it? Yes, of course it does. What you need to watch out for is code like: EnumerateFrogs(True); Nobody reading that can infer what the argument does.
  3. David Heffernan

    Converting C struct to Delphi

    That's not a problem with the Delphi side of things, that would be a basic design flaw of the library. If the consumer of the library has to call functions that it can't access, in order to use the library, then the library is unusable. You are better off not to speculate and guess like this. If the asker has a question, trust them to ask it.
  4. David Heffernan

    Converting C struct to Delphi

    Not really. You still declare it as a pointer and call the library function to open the file, and a pointer is returned. Only the library needs to know the implementation. It's a pointer to an opaque struct.
  5. David Heffernan

    Converting C struct to Delphi

    Then an untyped pointer will do.
  6. David Heffernan

    Converting C struct to Delphi

    This question is only useful to you if the answer is yes. The answer is no. And you are none the wiser. What you perhaps should have asked about was the underlying reason why you are concerned with a FILE*
  7. And my point is that you are giving yourself a false sense of security. It will take you extra time to develop your own licensing system, and then it gets cracked anyway. You may as well use a standard off the shelf tool and save yourself the time. Plus your paying users are able to use a system that they are familiar with for other software.
  8. If somebody wants to crack your program then your home brew protection won't hold up either.
  9. This won't work either.
  10. All of these security hardware devices are crackable. HASP has a terrible record. And the prices they charge are just ludicrous. You should view these things as a means to help your paying customers use the right amount of licences. They are not going to help you stop hackers cracking your program.
  11. All of this advice is kinda pointless if the attacker is inside your building!
  12. David Heffernan

    swagger help needed

    You said "stolen" which seemed odd. I don't know where you get your monetary figures from.
  13. David Heffernan

    Converting C struct to Delphi

    Leave it as an enum, but set the right enum size http://docwiki.embarcadero.com/RADStudio/Sydney/en/Minimum_enumeration_size_(Delphi)
  14. David Heffernan

    Converting C struct to Delphi

    You missed the language member. And probably the enum is actually an int and so 4 bytes.
  15. David Heffernan

    swagger help needed

    I'm pretty sure that he chose to go to MS. And it looks like an inspired decision now. Look what he has built there.
  16. We've talked about this before I think. Stefan and I developed one for spring4d. You'll find it in the develop branch. As I'm sure you know, Timsort is stable.
  17. These days I use Timsort for this reason.
  18. You don't need a new control. You just need not to use it to store your data. Store your data in a non visual control.
  19. Paying the price for using a GUI control to hold your data, rather than to view your data.
  20. The funny thing about this, is that the RTL code that implements a concatenation does this: Sum the length of all input strings. Allocate a new string of that length. Loop through all the input strings, moving their content to the new string. Return that new string. So even if this was your bottleneck, the RTL is already optimised!! In that original post that you linked, you were concatenating two strings, but repeatedly in a loop. So you had one allocation per expression. Here you have a single expression concatenating 11 strings. And that also has one allocation, because the RTL is, in this instance, not stupid. Bottom line is that your code using Move should be slower!! Please, please, please, take on board the lesson that optimisation starts with first identifying, with confidence, what your bottleneck is. If you can just take that lesson, then you will save lots of your time (and ours).
  21. It's like we are talking two completely different languages.
  22. What is unclear is why you wrote the code using Move in the first place, since there's no reason to believe that it addresses the performance bottleneck, which you seem not to have identified yet, or even attempted to identify yet. It's not that your questions are unclear, it's that you are asking the wrong questions.
  23. An explanation of why you start trying to improve performance without first identifying the performance bottleneck.
  24. Why don't you find out what the bottleneck is first? I simply don't understand why you keep making the same mistakes over and over again.
  25. You aren't doing it effectively though, because you are still creating lots of intermediate string objects along the way. Your goal should be to create no intermediate string objects. In my own code which writes huge YAML files containing lots of numbers (both integer and floating point), I export without any heap allocation, without any intermediate string objects. I use functions like this: // disable range checks and overflow checks so that Abs() functions in case Value = Low(Value) {$R-} {$Q-} function CopyIntegerToAnsiBuffer(const Value: Integer; var Buffer: array of AnsiChar): Integer; var i, j: Integer; val, remainder: Cardinal; negative: Boolean; tmp: array [0..15] of AnsiChar; begin negative := Value<0; val := Abs(Value); Result := 0; repeat DivMod(val, 10, val, remainder); tmp[Result] := AnsiChar(remainder + Ord('0')); Inc(Result); until val=0; if negative then begin tmp[Result] := '-'; Inc(Result); end; Assert(Result<=Length(Buffer)); i := 0; j := Result-1; while i<Result do begin Buffer[i] := tmp[j]; Inc(i); Dec(j); end; end; {$IFDEF RANGECHECKSON}{$R+}{$ENDIF} {$IFDEF OVERFLOWCHECKSON}{$Q+}{$ENDIF} This performs the same job as IntToStr but writes to a user supplied buffer, rather than forcing a heap allocation and a new string. The user supplied buffer is stack allocated, and then gets pushed to the file using one of my buffered stream classes. I'm using ANSI characters here because the output encoding is UTF-8. I have similar code for floating point, but that's obviously much more complex. As an aside, this has the benefit that I can escape the tyranny of the RTL's broken code which converts between floating point and text. In summary though, I don't think you are going about this in the right way. You have not yet correctly identified the bottleneck in your code. I know I keep saying this, but it doesn't make it any less true each time I say it.
×