how to add/use external libraries in plugin
-
Hi,
I am trying to develop a plugin. The idea is simple I want to read zpl code to image. I have a Library to do that. but I am not able to include this in the template provided by np++. I have also tried different template proj for developing plugin but still I get file not found error if I use the library.I got to know that I need to merge dlls used and I did it with ILMerge, ILRepack with not luck.
ILMerge.exe /zeroPeKind /closed /log:debug.txt /allowDup /lib:C:\Users\josep\source\repos\zplTestViewer1\zplTestViewer1\bin\Debug-x64 /out:zplTestViewer1.dll zplTestViewer1.dll BarcodeStandard.dll BinaryKits.Zpl.Label.dll BinaryKits.Zpl.Viewer.dll HarfBuzzSharp.dll Microsoft.Bcl.AsyncInterfaces.dll Microsoft.Win32.Primitives.dll netstandard.dll SkiaSharp.dll SkiaSharp.HarfBuzz.dll zxing.dll zxing.presentation.dll
so I am trying to understand is it possible to include external libraries into np++ plugins; if so how…? do we have any doc or tuts fo that…?
btw I am new to all this suff. need help.
-
@Joseph-Samuel Ah, thats all related to .NET stuff.
but still I get file not found error if I use the library
What is the source of this error? Is this .NET exception?
-
@Alexander-Verbitsky, I have started a new project with https://github.com/kbilsted/NotepadPlusPlusPluginPack.Net and I dont see any file not found error but I see below error in the np++ screen
I dont see any error in the output log in visual studio. below is the only line I have added to the default code given by template
I am not sure how to check np++ logs. can you help me…?output log in visual studio
'notepad++.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'notepad++.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Program Files\Notepad++\plugins\MyNppPlugin1\MyNppPlugin1.dll'. Symbols loaded. 'notepad++.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'notepad++.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'notepad++.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. The program '[11144] notepad++.exe: Program Trace' has exited with code 0 (0x0). The program '[11144] notepad++.exe' has exited with code 0 (0x0).
-
@Joseph-Samuel
Have you tried setting a breakpoint in the function that you want to debug and compiling in debug mode? -
Yes, I have tried breakpoint but if I add below line
IPrinterStorage printerStorage = new PrinterStorage();
compiler is not coming till that break point, if I remove the above line compiler is stopping at the break point, even if I dont remove below line
using BinaryKits.Zpl.Viewer;
The compiler is also coming here but not sure what’s going on in there…
Also tried adding breakpoints in different .cs files, but till np++ loaded on screen compiler is stopping at break points but once np++ is fully loaded and when I click the plugin option(for my plugin) in np++, compiler is not stopping at any breakpoint. it straight up throws error as below (No error in console output).
-
Could it be that the C# GC (Garbage Collector) did its job too early!?
Is your project publicly available somewhere? -
Let’s take a moment to consider what the error message dialog really means. It says that
14
was passed torunPluginCommand
, referring to this overload of thePluginsManager::runPluginCommand
method.What does that method do? It calls a function through a pointer that it finds using
i
to index an array of function pointers,_pluginsCommands
.Does 14 seem like a valid index for a plugin with only a few commands? N++ is supposed to learn the correct number from
getFuncsArray
, a core interface method taking a pointer to anint
(to receive the number of commands) and returning an array of pointers to those commands.@Joseph-Samuel, pay close attention to the
nbF
variable (or whatever your template calls it) in this method especially:[DllExport(CallingConvention = CallingConvention.Cdecl)] static IntPtr getFuncsArray(ref int nbF) { nbF = PluginBase._funcItems.Items.Count; return PluginBase._funcItems.NativePointer; }
If
PluginBase._funcItems
orPluginBase._funcItems.Items
isnull
, no .NET exception will be thrown. “Unmanaged” code fails like C++ would, with a segmentation fault, andnbF
will be left uninitialized except for a random value like 14. -
@Ekopalypse
I am not sure what you are saying I am new to these things (started .net with building this plugin). Yes I have pushed the code to git. pls look into it… https://github.com/BJSam/npp_plugin_tst/blob/8dcac2bf7f45bd1680e89525abc7f08db5578abe/MyNppPlugin1/Main.cs#L70 -
If PluginBase._funcItems or PluginBase._funcItems.Items is null, no .NET exception will be thrown. “Unmanaged” code fails like C++ would, with a segmentation fault, and nbF will be left uninitialized except for a random value like 14.
Thanks for looking into this. I got it on a high level but how come this line is affecting the entire command, if I remove that line its working without any error, if I add that line I am getting error. if you have time pls look into the proj
-
@Joseph-Samuel said in how to add/use external libraries in plugin:
Thanks for looking into this. I got it on a high level but how come this line is affecting the entire command, if I remove that line its working without any error, if I add that line I am getting error. if you have time pls look into the proj
You will learn far more by doing the work yourself. It’s good that you seem to have isolated the issue to what seems like one line of code. Do debug dumps or debugger breakpoints to see if the values in your variables are what you expect them to be. Break the line down into smaller parts. Read the manuals and documentation carefully for each of the small parts you are dealing with. Maybe you have discovered someone else’s bug but more likely something is happening in the code that you did not expect or assume would happen.
-
Thanks for sharing the code. The issue is something internal to the
BinaryKits.Zpl.Viewer
assembly. Even though it’s definitely in the load path, any attempt to instantiateIPrinterStorage
throws an exception. It can’t be debugged without installing theBinaryKits.Zpl.Viewer
symbols package, assuming the BinaryKits.Zpl project has published one.Try this:
namespace Kbg.NppPluginNET { // FIXME: instantiating IPrinterStorage throws an exception public class MyPrinterStorage // : BinaryKits.Zpl.Viewer.IPrinterStorage { public MyPrinterStorage() { MessageBox.Show(this.ToString()); } public void AddFile(char storageDevice, string fileName, byte[] data) { } public byte[] GetFile(char storageDevice, string fileName) => new byte[0xFF]; public override string ToString() => "Hello N++!"; } class Main { // . . . internal static void myMenuFunction() { MyPrinterStorage printerStorage = new MyPrinterStorage(); } // . . . } // . . . }
Confirm that
Plugins > MyNppPlugin1 > MyMenuCommand
runs OK.Now turn
MyPrinterStorage
into an instance ofIPrinterStorage
:public class MyPrinterStorage : BinaryKits.Zpl.Viewer.IPrinterStorage { // . . . }
Confirm that
Plugins > MyNppPlugin1 > MyMenuCommand
throws an exception.I think you may be mixing incompatible Framework versions. Your best alternative would be including
BinaryKits.Zpl.Viewer
as a project reference and building it yourself. -
BinaryKits.Zpl.Viewer as a project reference and building it yourself.
sure, thanks for the suggestion. will try that way…