Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

5 Neutral

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Thanks, got it! What I needed to do was: DummyPointer := Pointer(DummyObject);
  2. Hi there, when a TObject is instantiated, the following function is called: TObject.NewInstance: TObject; The code in this function is straightforward. It calls GetMem with the InstanceSize to allocate the necessary memory for the object. GetMem returns a pointer to the allocated memory space. class function TObject.NewInstance: TObject; begin Result := InitInstance(_GetMem(InstanceSize)); {$IFDEF AUTOREFCOUNT} Result.FRefCount := 1; {$ENDIF} end; The pointer to the allocated memory is passed to TObject.InitInstance(Instance: Pointer): TObject; This function is implemented in assembler. I do not understand what happens here. I am struggling to understand the relationship between the memory address returned by GetMem and the pointer address of the instantiated TObject. Look at this very simple code: DummyObject := TObject.Create; // DummyObject is declared as TObject DummyPointer := @DummyObject; // DummyPointer is declared as Pointer For example: With the debugger I can see that the call to GetMem returned the address: 04AEFA60 (in decimal 78576224) But DummyPointer is pointing to the following address: 69FC6BE0 (in decimal 1778150368) The addresses are completely unrelated. Does anyone have an explanation for this? I tried the same with TStringList. The GetMem address and the pointer address are also completely different. The delta between them is also different than the TObject delta. However for objects derived from TInterfacedObject there is a constant delta of 12 bytes, between the GetMem address and the pointer address. Why do I need this? I have the GetMem address which was used to instantiate a given object. I need to be able to convert the GetMem address to the object pointer address. That way I can obtain a reference to the TObject which I can then Rtti inspect. Thank you!
  3. This is the best solution I have found so far. It might be of use to someone else. I call GetMemoryManager to retrieve the FastMM memory manager and keep a reference to it. I then register my own memory manager. I only provide new implementations of GetMem and FreeMem. For all other calls I just forward the call to the FastMM memory manager. In my implementation of GetMem, I first delegate the call to the FastMM memory manager. I then call the FastMM function DetectClassInstance. {Returns the class for a memory block. Returns nil if it is not a valid class} function DetectClassInstance(APointer: Pointer): TClass; I was actually not expecting this to work, as I thought that calling this function at this stage would be way too early, and the call would always return nil. But to my pleasant surprise, it works. It returns the TClass for the just allocated memory block. 🙂
  4. Yes we do use weak references to avoid circular references. We only pass delphi interfaces to .NET and we rely on the .NET COM interop functionallity to manage the delphi object lifetime.
  5. We can compile our app with or without runtime packages. Unfortunately AQ Time crashes whenever I load our exe and it is NOT using runtime packages. I suspect that the problem is related to some third paty component, as I had used AQTime after the Win10 creators update. It was slow, but at least I could work with it.
  6. @Pawel Piotrowski We do use madExcept. I need the leak report between snapshots though. While the application is still runnning.
  7. @PeterBelow Our program is leaking memory. If I perform a certain calculation, there are some left-over objects that should no longer be referenced, but are alive. What I need is the ability to create snapshots while the program is running. That way I can compare two snapshots and figure out which objects are still alive in the later snapshot and of course be able to have the callstack to how these objects were created. In the past I have used the AQTime allocation profiler for investigating such issues. The problem is that AQtime has become practically unusable for us. Performing a particular calculation while AQTime is attached takes forever. Our app is a Delphi App, but makes heavy use of .NET and unmanaged (c++) dll's. So far I have not been able to figure out what the reason for the massive AQTime slowdown is. So I extended an internal tool that we use for debugging with the functionality I described above. In order to have an object be taken into account, I need to derive from a special base class. This works well, is what I need. At a any point in time I have insight into live objects (incl. callstack, and can also RTTI-Inspect them). I am just looking for a way of avoiding having to change the base classes of the objects that I wish to inspect, and automatically take all objects into account. Unfortunately our base classes inherit directly from TInterfacedObject. There are also many, many classes that inherit directly from TInterfacedObject. That is why I would need to change many classes to take them all into account. Maybe I just need to bite the bullet and build in a common base class. That would would make it really easy...
  8. Hi there, I need to be notified whenever any TObject is created/freed. (for debugging purposes). I have not found anything so far. Maybe someone knows of a way? Two ideas I have are: Look deeper into FastMM4. Maybe FastMM provides some mechanism to be notified of such events. See if it is possible to hijack the TObject Create and Destroy functions. Replace them with a function of mine, and then call the original function afterwards. My function would be acting like some sort of tranparent proxy. As of now I have no idea how to accomplish this, but this is something I want to investigate. Would be very grateful is someone has more insight into this.
  9. @Attila Kovacs I gave it another go, and it does indeed work. Don't know what I did wrong the first time I tried... I also tested if multiple TApplicationEvents can be used simultaneously. This also works well. Thank you!
  10. Thx, good to know!! I will give it another shot tomorrow. 🙂
  11. @dummzeuch this plugin is only for internal use. I am chaining the event. For my use case the TApplicationEvents class which was recommended by @Attila Kovacs seems to be a good choice. Unfortunately, I could not get it to work. Have you used this class inside an ide plugin? If I understand correctly this would allow multiple event subcribers to coexist.
  12. @Attila Kovacs yes I am keeping a reference to the previous handler in case it was set. I would prefer to use TApplicationEvents though. Thx for the tip. Unfortunately I could not get it to work. FApplicationEvents := TApplicationEvents.Create(EditWindow.Form);// nil); FApplicationEvents.OnMessage := ApplicationEventsMessage; The callback method (ApplicationEventsMessage) was never called. I also tried without setting an owner.
  13. @Uwe Raabe The file is read-only. So unfortunately, the EditorViewModified event will never be triggered. I got it to work. Here is a high level overview of how it works, in case it might be of help to someone else: I react to the INTAEditServicesNotifier.EditorViewModified event. This is triggered whenever a new editor window is activated. Here I can easily detect whether the source file is read only or not, using EditView.Buffer.IsReadOnly. The trickiest part was then getting the handle of the editor control window (TEditControl). The Open Tools Api provides no functionality for that. It does provide you with the IDE's TCustomForm though (INTAEditWindow.Form). With the form you can find the editor control by searching for a child component with ClassName = 'TEditControl' and ComponentName = 'Editor'. Instead of working with a Windows Hook, I just added a handler for Application.OnMessage. procedure TEditorNotifier.ApplicationEventsMessage(var Msg: tagMSG; var Handled: Boolean); begin if (Msg.message = WM_KEYDOWN) and (FEditControl.Handle = Msg.hwnd) then begin // magic happens... end; if not Handled and Assigned(FPreviousMessageEvent) then FPreviousMessageEvent(Msg, Handled); end;
  14. Hi there, I am using the Open Tools Api to develop a plugin for the Delphi IDE. What I would like to be able to do, is detect that a user has pressed a key in the code editor window. If the active file (module) is read-only I would then like to take a specific action. Unfortunately the Open Tools Api does not seem to offer the functionality I require (be notified of a key press in the editor window). The only other option I can think of, would be to use a Windows Hook. SetWindowsHookEx(WH_KEYBOARD, ... Maybe someone knows if there is a better way to achieve this instead of having to resort to a Windows Hook. Thanks!!
  15. Thanks for the reply! Registry seems to be fine though. My colleague was just able to fix the problem. He copied these two dll's: dcc32260.dll dcc32250.dll from another PC. Somehow they were missing on his PC. That fixed the problem. Anyhow something strange seems to have gone wrong during installation.