Hi Folks,
Finally I found the solutions to my problems. Last night I couldn't sleep until I got it.
As I thought, the reason for the first problem was the assignement of one string type to a different one.
In the file iSQP0511DLLSource\DLLiSED.pas I saw, that the Delphi return type of the function iSEDRenderPageToString was PChar, which is only a pointer to characters with no length info. In the file iSQP0511DotNet.cs, which is the DLL wrapper for .NET, the function iSEDRenderPageToString is imported from iSEDQuickPDF.dll as a string returning function and the wrapper function RenderPageToString calls iSEDRenderPageToString with the same parameters and returns the resulting string. Obviously the length info will be lost when the assignement from the pointer to the string is executed. The in this case used C# string constructor casts the pointer from the return value to a string, which only goes to the first contained zero. The original string with the proper length (I think) will be destroyed by the garbage collection. My task was, to find a way to avoid this mechanism. Instead of importing and using the function iSEDRenderPageToString as a string returning function, I imported and used it as a pointer returning function, which it actually is. To achieve this in C#, the function must use the "unsafe" statement and the wrapper library must be compiled with the /unsafe option. So the file iSQP0511DotNet.cs has been patched the following way: old import: [DllImport("iSEDQuickPDF.dll")] static extern string iSEDRenderPageToString(int iDPI, int iPage, int iOptions);
new import: [DllImport("iSEDQuickPDF.dll")] static extern sbyte* iSEDRenderPageToString(int iDPI, int iPage, int iOptions);
old implementation of the wrapper function: public string RenderPageToString(int DPI, int Page, int Options) { return iSEDRenderPageToString(DPI, Page, Options); }
new implementation of the wrapper function: public string RenderPageToString(int DPI, int Page, int Options) { unsafe { return new System.String( iSEDRenderPageToString(DPI, Page, Options), 0, StringResultLength() ); } }
Using this patch, the function RenderPageToString does, what it is expected to do. The only drawback of my patch is, the library has to be compiled slightly different as described by iSED (using the option /unsafe). Maybe later on, I will try to the job better. For now the result is satisfactory to me.
The second problem (assigning the string to an Image object) was just finding the proper functions. Hints I have found in the file of which chicks posted the URL. Thanks!
To show the effects of the original iSEDQuickPDF 5.11 DLL wrapper for .NET and the patched one, you can write a C# console program (call it Test.cs) and put it to somewhere what I will call the working directory. Test.cs should have the following content: using System; using System.IO; using System.Text; using System.Drawing; using iSED = SEDTech.iSED; class Test { public static void Main() { iSED.QuickPDF qp = new iSED.QuickPDF(); Console.Write( "iSEDQuickPDF version: " ); Console.WriteLine( qp.LibraryVersion() ); qp.UnlockKey( "your unlock key goes here" ); Console.WriteLine( "Loading PDF file..." ); qp.LoadFromFile( "Test.pdf" ); Console.WriteLine( "Rendering page 1 to file..." ); qp.RenderDocumentToFile(72, 1, 1, 0, "Page_%p_of_Test_A.bmp" ); Console.WriteLine( "Rendering page 1 to string..." ); string bitMapStr = qp.RenderPageToString( 72, 1, 0 ); Image img = Image.FromStream( new MemoryStream( Encoding.Default.GetBytes( bitMapStr ) ) ); Console.WriteLine( "Saving image from string..." ); img.Save( "Page_1_of_Test_B.bmp", System.Drawing.Imaging.ImageFormat.Bmp ); Console.WriteLine( "Finished!" ); } }
Don't forget to replace the parameter string for the function UnlockKey with your unlock key.
From the file iSQP0511DLL.zip extract iSEDQuickPDF.dll and iSQP0511DotNet.cs to your working directory. Rename iSQP0511DotNet.cs to iSQP0511DotNet0.cs and make a copy of it, named iSQP0511DotNet1.cs. To iSQP0511DotNet1.cs apply the patches described before.
Then create a batch file (you may call it build.cmd) in the working directory with the following content: csc /out:iSED0.dll /t:library iSQP0511DotNet0.cs csc /out:iSED1.dll /t:library /unsafe iSQP0511DotNet1.cs csc /out:Test0.exe /t:exe /reference:iSED0.dll Test.cs csc /out:Test1.exe /t:exe /reference:iSED1.dll Test.cs
Execute build.cmd, which should create the two files Test0.exe and Test1.exe in the working directory.
Copy a PDF file you like to the working directory (don't use the "iSEDQuickPDF 5.11 Reference Guide.pdf") and rename it to Test.pdf. Open a command line window and execute Test0.exe, see the results and then execute Test1.exe to compare with.
Test0.exe only will produce Page_1_of_Test_A.bmp (and some temporary files) and trows an exeption while Test1.exe will output Page_1_of_Test_A.bmp and Page_1_of_Test_B.bmp. If you compare the two BMP-files you see, they differ in a few bytes. I don't know why. When you open the two BMP-files with a Graphic Viewer, you won't see any difference.
As I indicated before, the file "iSEDQuickPDF 5.11 Reference Guide.pdf" causes problems. Page_1_of_Test_A.bmp produced from it, in a Graphik Viewer shows only a blank page, while Page_1_of_Test_B.bmp appears to be a good bitmap. So the work is not over yet. But now I will concentrate on what I wanted to do one week ago, hoping all goes well.
Best regards, Pirmin
|