New cross-platform plugin template for Delphi developers
-
getFuncsArray is called by Npp itself to find out which methods your plugin provides and the ID defined there must match the one when the dialog is registered.
Unfortunately I have no idea about Delphi. -
As a quick&dirty check i wrote a âhaltâ inside the function, but the process didnât stop itâs execution; so i assumed itâs not called from outside.
-
that sounds strange if
halt
is supposed to terminate the running process, but I can assure you that without calling getFuncsArray through Npp you will not see your plugin being loaded. -
@Ekopalypse Coming back to npp plugin stuff again first time after, oh, 11 years later (now with Lazarus), iâm now still unsure about debugging it. A second quick&dirty check instead therefore for now, had been to skip the contents of function getFuncsArray completely - for to see if anything changes at all. No changes in behaviour âŚ
-
@klaus101
Unfortunately, I canât help you with Delphi, but I will try to explain what is going on under the hood.
Npp calls getFuncsArray in your plugin to find out which functions and therefore which menu items your plugin provides.
As the name suggests, this is an array of FuncItem structures and in each FuncItem structure a field called _cmdID is filled with an ID and a field _pFunc with the function pointer of the respective plugin function.
Later Npp checks via the config.xml and the DockingManager section whether your plugin is listed there and if so, the ID from the config.xml is compared with the ID from the FuncsArray and if something is found, the corresponding function is called via the function pointer.
If you have now removed all the menu items (FuncItems) except for the about entry and an entry with ID 0 for your plugin is found in the config.xml, the about function pointer is then called. -
@Ekopalypse said in New cross-platform plugin template for Delphi developers:
that sounds strange if
halt
is supposed to terminate the running process [âŚ]Like @klaus101 observed, it does not kill the
notepad++.exe
process because the Free Pascal version of the template does not own the main application handle (the way the Delphi version â unfortunately â does, for reasons that go back to Delphiâs history as the precursor to .NET, as .NET plugins likewise share the notepad++ process ID).@klaus101 said in New cross-platform plugin template for Delphi developers:
iâm now still unsure about debugging it.
Thatâs a problem with DLLs in general and with plugin DLLs in particular. For example, the
getFuncsArray
function is called bynotepad++.exe
through a function pointer, i.e., a memory address pointing to where the compiled Pascal code is sitting in the DLL. I donât know if the Lazarus IDEâs debugger can even trace that; you would have to first of all attach it to the runningnotepad++.exe
process, and the function call happens so early you will miss it.In general, the stuff in the templateâs DllExports unit should be considered read-only, except for the
DLL_ATTACH
hook where you construct your plugin object.As for tooling, I suggest using GNU Debug if you want to monitor every step of the DLL lifecycle. My personal setup uses VS Code with the C++ Tools extension. All I do is create a launch profile based on the
cppdbg
template, e.g.,{ "version": "0.2.0", "configurations": [ { "name": "Notepad++", "request": "launch", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "type": "cppdbg", "MIMode": "gdb", "miDebuggerPath": "${env:LAZARUS_DIR}\\mingw\\x86_64-win64\\bin\\gdb.exe", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Set Disassembly Flavor to Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true } ], "logging": { "moduleLoad": true }, "program": "${full_path_to}\\notepad++.exe" } ] }
Save this as
.vscode/launch.json
and open the root source folder in VS Code. Replace"${full_path_to}\\notepad++.exe"
to the one where the plugin is installed. Every Lazarus toolchain comes with a compatible version of gdb, so replace${env:LAZARUS_DIR}\\mingw\\x86_64-win64\\bin\\gdb.exe
with the actual path on your PC.After that, you should be able to set breakpoints (by clicking on the line number margin) and start the editor with the
F5
key. -
@rdipardo and @Ekopalypse,
many thanks for your valuable explanations!In Lazarus, for debugging DLLs, one can set a âhost applicationâ to execute with; so one is able to set breakpoints in the pascal code etc.
All plugin templates i tried before, crashed ⌠at addresses outside the scope of the pascal code though.
Your template rdipardo was the first one i found that showed up as a really fine working example :-) :-). Unfortunately, after setting the host application, the ârunâ functionality is not enabled. For all crashing templates, it had been enabled. I just kicked a question in the Laz. newsgroup whatâs required to enable it.Could you at least, for the moment, confirm (or maybe not confirm, so thatâs my fault) if you could reproduce? By commenting a few lines, and retry?
I try to describe more precise what happens:
-
First, a session with the unchanged / full menu. - config.xml says:
<PluginDlg pluginName=âHelloWorld.dllâ id=â2â curr=â0â prev=â-1â isVisible=âyesâ /> -
Then, shrinked menu creation to the three items âLoad docking formâ, Separator, âAboutâ
-
Removed the old entry for pluginName=âHelloWorld.dllâ from the config.xml for to have a clean restart
-
Start NPP with the new compiled DLL and click menu item âLoad docking formâ, and close NPP again
-
NPP rewrites the new line:
<PluginDlg pluginName=âHelloWorld.dllâ id=â2â curr=â0â prev=â-1â isVisible=âyesâ />
So far all looks fine! -
Now restart NPP again ⌠and, what will appear at first, is the demo About box.
-
Afterwards, config.xml entry showed up unchanged:
<PluginDlg pluginName=âHelloWorld.dllâ id=â2â curr=â0â prev=â-1â isVisible=âyesâ />
I understand that, if some first pointers a invalid, but the last one (for About) keeps to be valid, this last one will be used.
But who stored the unbalanced info where?â> Btw: i fear that this specific issue - and the question about the dark theme - will run extremely out of scope of this specific topic, which wants to inform about the new template. Better to continue in/as a new topic if needed?
-
-
@klaus101 said in New cross-platform plugin template for Delphi developers:
Btw: i fear that this specific issue - and the question about the dark theme - will run extremely out of scope of this specific topic, which wants to inform about the new template. Better to continue in/as a new topic if needed?
If @rdipardo wants it to be split off, to avoid cluttering the main Delphi-plugin-template Topic, I could use my moderator power to split off all the recent posts to that new topic, if you give me a meaningful name to use for the new Topic. But if @rdipardo doesnât mind it staying here, thatâs fine by me.
-
@PeterJones, thank you for your proposal!
Itâs related to Delphi as well as Lazarus development environments (would be interesting to know btw if the issue (if any) does show up with Delphi too).If @rdipardo wants it to be split off, iâd see two topics here:
Plugin template for Delphi and Lazarus developers: question about modifying the pluginâs demo menu (Lazarus)
Plugin template for Delphi and Lazarus developers: question about possibility to skip dark mode theme handling -
@PeterJones: the wiki is now up, so this thread can be locked đ, please and thank you.
-