DinkToPdf icon indicating copy to clipboard operation
DinkToPdf copied to clipboard

Use of Dinktopdf lib in .Net framework app unbalances the stack

Open fashrista opened this issue 4 years ago • 0 comments

I have a .Net Framework 4.8 app and in it I need to convert some html/css into pdf.

I have sampled a demo project of DinkToPdf. This worked in .NET core app and in Xamarin Forms app (where I ocasionally get Memory accsess violation Exception), but cannot get it to function in a .Net Framewrk app.

I have added DinkToPDF v1.0.8 to my project's reference folder via NugetPackageManager. I have looked into package dependencies and made shure that all are up to required versions. There is a native lib that I needed to copy to my projects root becouse the DinkToPdf uses it: libwkhtmltox.dll (I have tryed different versions of this) I have also tryed RndUsr0.DinkToPdf package, which "Upgraded to .NET Standard 2.0, .NET Core 2.1, wkhtmltopdf v0.12.5." but had no beter results.

What happens: When my app calls basicConverter.Converet(HtmlToPdfDocument doc)I get an Exception:"DinkToPdf.WkHtmlToXBindings::wkhtmltopdf_init' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.' "

public static void ConvertToPdf()
    {
        //load native lib libwkhtmltox.dll
        var architectureFolder = (IntPtr.Size == 8) ? "64 bit" : "32 bit";
        var wkHtmlToPdfPath = Path.Combine(AppContext.BaseDirectory, $"wkhtmltox\\v0.12.4\\{architectureFolder}\\libwkhtmltox.dll");//here a libwkhtmltox.dll needs to be stored 
        IntPtr pDll = NativeMethods.LoadLibrary(wkHtmlToPdfPath);
        if (pDll == IntPtr.Zero)
        {
            throw new FileNotFoundException("-- Cannot load libwkhtmltox == a dll used for html to pdf convertion --");
        }
        var converter = new BasicConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            }
        };
        ObjectSettings objectSettings = new ObjectSettings()
        {
            PagesCount = true,
            HtmlContent = html,
            WebSettings = { DefaultEncoding = "utf-8"}
        };
        doc.Objects.Add(objectSettings);
        byte[] pdf = converter.Convert(doc);//!!! THIS IS THE POINT THAT THROWS UP
        string outputFile = Path.Combine(AppContext.BaseDirectory, "ImageFromHtmnl.pdf");
        using (FileStream stream = new FileStream(outputFile, FileMode.Create))
        {
            stream.Write(pdf, 0, pdf.Length);
        }
    }
 static class NativeMethods
    {
        [DllImport("kernel32.dll"/*,CallingConvention = CallingConvention.Cdecl*/)]
        public static extern IntPtr LoadLibrary(string dllToLoad);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);


        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);

        public static string GetLibraryPathname(string filename)
        {
            // If 64-bit process, load 64-bit DLL
            bool is64bit = System.Environment.Is64BitProcess;

            string prefix = "Win32";

            if (is64bit)
            {
                prefix = "x64";
            }

            var lib1 = prefix + @"\" + filename;

            return lib1;
        }
    }

To conclude: I would expect the DinkToPdf nuget package with libwkhtmltox.dll native lib to function in a .NET Framework app just as well as it functions in a .NET Core app. But it does not.

What have I missed?

fashrista avatar Sep 13 '19 09:09 fashrista