实现用C#和VB.NET调用Ghostscript的API,把Postscript文件转为PDF文件。

利用 Ghostscript提供的gsapi_vb实现转postscript为PDF,进一步成功把VB.NET代码转为C#。
所用GhostScript为AFPL Ghostscript 8.53
附上GhostScript提供的VB.NET代码:
None.gif '  Copyright (c) 2002 Dan Mount and Ghostgum Software Pty Ltd
None.gif'
None.gif'
 Permission is hereby granted, free of charge, to any person obtaining 
None.gif'
 a copy of this software and associated documentation files (the 
None.gif'
 "Software"), to deal in the Software without restriction, including
None.gif'
 without limitation the rights to use, copy, modify, merge, publish, 
None.gif'
 distribute, sublicense, and/or sell copies of the Software, and to
None.gif'
 permit persons to whom the Software is furnished to do so, subject to 
None.gif'
 the following conditions:
None.gif'
None.gif'
 The above copyright notice and this permission notice shall be
None.gif'
 included in all copies or substantial portions of the Software.
None.gif'
None.gif'
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
None.gif'
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
None.gif'
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
None.gif'
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
None.gif'
 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
None.gif'
 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
None.gif'
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
None.gif'
 SOFTWARE.
None.gif

None.gif
None.gif
'  This is an example of how to call the Ghostscript DLL from
None.gif'
 Visual Basic.NET.  There are two examples, one converts
None.gif'
 colorcir.ps to PDF, the other is like command line Ghostscript.
None.gif'
 The display device is not supported.
None.gif'
None.gif'
 This code is not compatible with VB6.  There is another
None.gif'
 example which does work with VB6.  Differences include:
None.gif'
 1. VB.NET uses GCHandle to get pointer
None.gif'
    VB6 uses StrPtr/VarPtr
None.gif'
 2. VB.NET Integer is 32bits, Long is 64bits
None.gif'
    VB6 Integer is 16bits, Long is 32bits
None.gif'
 3. VB.NET uses IntPtr for pointers
None.gif'
    VB6 uses Long for pointers
None.gif'
 4. VB.NET strings are always Unicode
None.gif'
    VB6 can create an ANSI string
None.gif'
 See the following URL for some VB6 / VB.NET details
None.gif'
  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvb600/html/vb6tovbdotnet.asp
None.gif

None.gif
Option   Explicit   On  
None.gif
None.gif
Imports  System.Runtime.InteropServices
None.gif
ExpandedBlockStart.gifContractedBlock.gif
Module gsapi Module gsapi
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Declare Sub CopyMemory()Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As IntPtr, ByVal source As IntPtr, ByVal bytes As Long)
InBlock.gif
InBlock.gif    
'------------------------------------------------
InBlock.gif
    'UDTs Start
InBlock.gif
    '------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
    <StructLayout(LayoutKind.Sequential)> Public Structure GS_RevisionStructure GS_Revision
InBlock.gif        
Public strProduct As IntPtr
InBlock.gif        
Public strCopyright As IntPtr
InBlock.gif        
Public intRevision As Integer
InBlock.gif        
Public intRevisionDate As Integer
ExpandedSubBlockEnd.gif    
End Structure

InBlock.gif    
'------------------------------------------------
InBlock.gif
    'UDTs End
InBlock.gif
    '------------------------------------------------
InBlock.gif

InBlock.gif    
'------------------------------------------------
InBlock.gif
    'Callback Functions Start
InBlock.gif
    '------------------------------------------------
InBlock.gif
    'These are only required if you use gsapi_set_stdio
ExpandedSubBlockStart.gifContractedSubBlock.gif
    Public Delegate Function StdioCallBack()Function StdioCallBack(ByVal handle As IntPtr, ByVal strptr As IntPtr, ByVal count As IntegerAs Integer
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Function gsdll_stdin()Function gsdll_stdin(ByVal intGSInstanceHandle As IntPtr, ByVal strz As IntPtr, ByVal intBytes As IntegerAs Integer
InBlock.gif        
' This is dumb code that reads one byte at a time
InBlock.gif
        ' Ghostscript doesn't mind this, it is just very slow
InBlock.gif
        If intBytes = 0 Then
InBlock.gif            gsdll_stdin 
= 0
InBlock.gif        
Else
InBlock.gif            
Dim ich As Integer = Console.Read()
InBlock.gif            
If ich = -1 Then
InBlock.gif                gsdll_stdin 
= 0 ' EOF
InBlock.gif
            Else
InBlock.gif                
Dim bch As Byte = ich
InBlock.gif                
Dim gcByte As GCHandle = GCHandle.Alloc(bch, GCHandleType.Pinned)
InBlock.gif                
Dim ptrByte As IntPtr = gcByte.AddrOfPinnedObject()
InBlock.gif                CopyMemory(strz, ptrByte, 
1)
InBlock.gif                ptrByte 
= IntPtr.Zero
InBlock.gif                gcByte.Free()
InBlock.gif                gsdll_stdin 
= 1
InBlock.gif            
End If
InBlock.gif        
End If
ExpandedSubBlockEnd.gif    
End Function

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Function gsdll_stdout()Function gsdll_stdout(ByVal intGSInstanceHandle As IntPtr, ByVal strz As IntPtr, ByVal intBytes As IntegerAs Integer
InBlock.gif        
' If you can think of a more efficient method, please tell me!
InBlock.gif
        ' We need to convert from a byte buffer to a string
InBlock.gif
        ' First we create a byte array of the appropriate size
InBlock.gif
        Dim aByte(intBytes) As Byte
InBlock.gif        
' Then we get the address of the byte array
InBlock.gif
        Dim gcByte As GCHandle = GCHandle.Alloc(aByte, GCHandleType.Pinned)
InBlock.gif        
Dim ptrByte As IntPtr = gcByte.AddrOfPinnedObject()
InBlock.gif        
' Then we copy the buffer to the byte array
InBlock.gif
        CopyMemory(ptrByte, strz, intBytes)
InBlock.gif        
' Release the address locking
InBlock.gif
        ptrByte = IntPtr.Zero
InBlock.gif        gcByte.Free()
InBlock.gif        
' Then we copy the byte array to a string, character by character
InBlock.gif
        Dim str As String
InBlock.gif        
Dim i As Integer
InBlock.gif        
For i = 0 To intBytes - 1
InBlock.gif            
str = str + Chr(aByte(i))
InBlock.gif        
Next
InBlock.gif        
' Finally we output the message
InBlock.gif
        Console.Write(str)
InBlock.gif        gsdll_stdout 
= intBytes
ExpandedSubBlockEnd.gif    
End Function

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Function gsdll_stderr()Function gsdll_stderr(ByVal intGSInstanceHandle As IntPtr, ByVal strz As IntPtr, ByVal intBytes As IntegerAs Integer
InBlock.gif        gsdll_stderr 
= gsdll_stdout(intGSInstanceHandle, strz, intBytes)
ExpandedSubBlockEnd.gif    
End Function

InBlock.gif    
'------------------------------------------------
InBlock.gif
    'Callback Functions End
InBlock.gif
    '------------------------------------------------
InBlock.gif

InBlock.gif    
'------------------------------------------------
InBlock.gif
    'API Calls Start
InBlock.gif
    '------------------------------------------------
InBlock.gif
    'Win32 API
InBlock.gif
    'GhostScript API
InBlock.gif
    '    Public Declare Function gsapi_revision Lib "gsdll32.dll" (ByVal pGSRevisionInfo As IntPtr, ByVal intLen As Integer) As Integer
ExpandedSubBlockStart.gifContractedSubBlock.gif
    Public Declare Function gsapi_revision()Function gsapi_revision Lib "gsdll32.dll" (ByRef pGSRevisionInfo As GS_Revision, ByVal intLen As IntegerAs Integer
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Declare Function gsapi_new_instance()Function gsapi_new_instance Lib "gsdll32.dll" (ByRef lngGSInstance As IntPtr, ByVal lngCallerHandle As IntPtr) As Integer
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Declare Function gsapi_set_stdio()Function gsapi_set_stdio Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr, ByVal gsdll_stdin As StdioCallBack, ByVal gsdll_stdout As StdioCallBack, ByVal gsdll_stderr As StdioCallBack) As Integer
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Declare Sub gsapi_delete_instance()Sub gsapi_delete_instance Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Declare Function gsapi_init_with_args()Function gsapi_init_with_args Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr, ByVal lngArgumentCount As IntegerByVal lngArguments As IntPtr) As Integer
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Declare Function gsapi_run_file()Function gsapi_run_file Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr, ByVal strFileName As StringByVal intErrors As IntegerByVal intExitCode As IntegerAs Integer
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Declare Function gsapi_exit()Function gsapi_exit Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr) As Integer
InBlock.gif    
'------------------------------------------------
InBlock.gif
    'API Calls End
InBlock.gif
    '------------------------------------------------
InBlock.gif

InBlock.gif    
'------------------------------------------------
InBlock.gif
    'User Defined Functions Start
InBlock.gif
    '------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
    Public Function StringToAnsiZ()Function StringToAnsiZ(ByVal str As StringAs Byte()
InBlock.gif        
' Convert a Unicode string to a null terminated Ansi string for Ghostscript.
InBlock.gif
        ' The result is stored in a byte array.  Later you will need to convert
InBlock.gif
        ' this byte array to a pointer with GCHandle.Alloc(XXXX, GCHandleType.Pinned)
InBlock.gif
        ' and GSHandle.AddrOfPinnedObject()
InBlock.gif
        Dim intElementCount As Integer
InBlock.gif        
Dim intCounter As Integer
InBlock.gif        
Dim aAnsi() As Byte
InBlock.gif        
Dim bChar As Byte
InBlock.gif        intElementCount 
= Len(str)
InBlock.gif        
ReDim aAnsi(intElementCount + 1)
InBlock.gif        
For intCounter = 0 To intElementCount - 1
InBlock.gif            bChar 
= Asc(Mid(str, intCounter + 11))
InBlock.gif            aAnsi(intCounter) 
= bChar
InBlock.gif        
Next intCounter
InBlock.gif        aAnsi(intElementCount) 
= 0
InBlock.gif        StringToAnsiZ 
= aAnsi
ExpandedSubBlockEnd.gif    
End Function

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Function AnsiZtoString()Function AnsiZtoString(ByVal strz As IntPtr) As String
InBlock.gif        
' We need to convert from a byte buffer to a string
InBlock.gif
        Dim byteCh(1As Byte
InBlock.gif        
Dim bOK As Boolean = True
InBlock.gif        
Dim gcbyteCh As GCHandle = GCHandle.Alloc(byteCh, GCHandleType.Pinned)
InBlock.gif        
Dim ptrByte As IntPtr = gcbyteCh.AddrOfPinnedObject()
InBlock.gif        
Dim j As Integer = 0
InBlock.gif        
Dim str As String
InBlock.gif        
While bOK
InBlock.gif            
' This is how to do pointer arithmetic!
InBlock.gif
            Dim sPtr As New IntPtr(strz.ToInt64() + j)
InBlock.gif            CopyMemory(ptrByte, sPtr, 
1)
InBlock.gif            
If byteCh(0= 0 Then
InBlock.gif                bOK 
= False
InBlock.gif            
Else
InBlock.gif                
str = str + Chr(byteCh(0))
InBlock.gif            
End If
InBlock.gif            j 
= j + 1
InBlock.gif        
End While
InBlock.gif        AnsiZtoString 
= str
ExpandedSubBlockEnd.gif    
End Function

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Function CheckRevision()Function CheckRevision(ByVal intRevision As IntegerAs Boolean
InBlock.gif        
' Check revision number of Ghostscript
InBlock.gif
        Dim intReturn As Integer
InBlock.gif        
Dim udtGSRevInfo As GS_Revision
InBlock.gif        
Dim gcRevision As GCHandle
InBlock.gif        gcRevision 
= GCHandle.Alloc(udtGSRevInfo, GCHandleType.Pinned)
InBlock.gif        intReturn 
= gsapi_revision(udtGSRevInfo, 16)
InBlock.gif        Console.WriteLine(
"Revision = " & udtGSRevInfo.intRevision)
InBlock.gif        Console.WriteLine(
"RevisionDate = " & udtGSRevInfo.intRevisionDate)
InBlock.gif        Console.WriteLine(
"Product = " & AnsiZtoString(udtGSRevInfo.strProduct))
InBlock.gif        Console.WriteLine(
"Copyright = " & AnsiZtoString(udtGSRevInfo.strCopyright))
InBlock.gif
InBlock.gif        
If udtGSRevInfo.intRevision = intRevision Then
InBlock.gif            CheckRevision 
= True
InBlock.gif        
Else
InBlock.gif            CheckRevision 
= False
InBlock.gif        
End If
InBlock.gif        gcRevision.Free()
ExpandedSubBlockEnd.gif    
End Function

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Public Function CallGS()Function CallGS(ByVal astrGSArgs() As StringAs Boolean
InBlock.gif        
Dim intReturn As Integer
InBlock.gif        
Dim intGSInstanceHandle As IntPtr
InBlock.gif        
Dim aAnsiArgs() As Object
InBlock.gif        
Dim aPtrArgs() As IntPtr
InBlock.gif        
Dim aGCHandle() As GCHandle
InBlock.gif        
Dim intCounter As Integer
InBlock.gif        
Dim intElementCount As Integer
InBlock.gif        
Dim iTemp As Integer
InBlock.gif        
Dim callerHandle As IntPtr
InBlock.gif        
Dim gchandleArgs As GCHandle
InBlock.gif        
Dim intptrArgs As IntPtr
InBlock.gif
InBlock.gif        
' Print out the revision details.
InBlock.gif
        ' If we want to insist on a particular version of Ghostscript
InBlock.gif
        ' we should check the return value of CheckRevision().
InBlock.gif
        CheckRevision(704)
InBlock.gif
InBlock.gif        
' Load Ghostscript and get the instance handle
InBlock.gif
        intReturn = gsapi_new_instance(intGSInstanceHandle, callerHandle)
InBlock.gif        
If (intReturn < 0Then
InBlock.gif            
Return (False)
InBlock.gif        
End If
InBlock.gif
InBlock.gif        
' Capture stdio
InBlock.gif
        Dim stdinCallback As StdioCallBack
InBlock.gif        stdinCallback 
= AddressOf gsdll_stdin
InBlock.gif        
Dim stdoutCallback As StdioCallBack
InBlock.gif        stdoutCallback 
= AddressOf gsdll_stdout
InBlock.gif        
Dim stderrCallback As StdioCallBack
InBlock.gif        stderrCallback 
= AddressOf gsdll_stderr
InBlock.gif        intReturn 
= gsapi_set_stdio(intGSInstanceHandle, stdinCallback, stdoutCallback, stderrCallback)
InBlock.gif
InBlock.gif        
If (intReturn >= 0Then
InBlock.gif            
' Convert the Unicode strings to null terminated ANSI byte arrays
InBlock.gif
            ' then get pointers to the byte arrays.
InBlock.gif
            intElementCount = UBound(astrGSArgs)
InBlock.gif            
ReDim aAnsiArgs(intElementCount)
InBlock.gif            
ReDim aPtrArgs(intElementCount)
InBlock.gif            
ReDim aGCHandle(intElementCount)
InBlock.gif            
For intCounter = 0 To intElementCount
InBlock.gif                aAnsiArgs(intCounter) 
= StringToAnsiZ(astrGSArgs(intCounter))
InBlock.gif                aGCHandle(intCounter) 
= GCHandle.Alloc(aAnsiArgs(intCounter), GCHandleType.Pinned)
InBlock.gif                aPtrArgs(intCounter) 
= aGCHandle(intCounter).AddrOfPinnedObject()
InBlock.gif            
Next
InBlock.gif            gchandleArgs 
= GCHandle.Alloc(aPtrArgs, GCHandleType.Pinned)
InBlock.gif            intptrArgs 
= gchandleArgs.AddrOfPinnedObject()
InBlock.gif            callerHandle 
= IntPtr.Zero
InBlock.gif
InBlock.gif            intReturn 
= gsapi_init_with_args(intGSInstanceHandle, intElementCount + 1, intptrArgs)
InBlock.gif
InBlock.gif            
' Release the pinned memory
InBlock.gif
            For intCounter = 0 To intElementCount
InBlock.gif                aGCHandle(intCounter).Free()
InBlock.gif            
Next
InBlock.gif            gchandleArgs.Free()
InBlock.gif
InBlock.gif            
' Stop the Ghostscript interpreter
InBlock.gif
            gsapi_exit(intGSInstanceHandle)
InBlock.gif        
End If
InBlock.gif
InBlock.gif        
' release the Ghostscript instance handle
InBlock.gif
        gsapi_delete_instance(intGSInstanceHandle)
InBlock.gif
InBlock.gif        
If (intReturn >= 0Then
InBlock.gif            CallGS 
= True
InBlock.gif        
Else
InBlock.gif            CallGS 
= False
InBlock.gif        
End If
InBlock.gif
ExpandedSubBlockEnd.gif    
End Function

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Private Function ConvertFile()Function ConvertFile() As Boolean
InBlock.gif        
Dim astrArgs(10As String
InBlock.gif        astrArgs(
0= "ps2pdf" 'The First Parameter is Ignored
InBlock.gif
        astrArgs(1= "-dNOPAUSE"
InBlock.gif        astrArgs(
2= "-dBATCH"
InBlock.gif        astrArgs(
3= "-dSAFER"
InBlock.gif        astrArgs(
4= "-r300"
InBlock.gif        astrArgs(
5= "-sDEVICE=pdfwrite"
InBlock.gif        astrArgs(
6= "-sOutputFile=c:\out.pdf"
InBlock.gif        astrArgs(
7= "-c"
InBlock.gif        astrArgs(
8= ".setpdfwrite"
InBlock.gif        astrArgs(
9= "-f"
InBlock.gif        astrArgs(
10= "c:\gs\gs7.04\examples\colorcir.ps"
InBlock.gif        
Return CallGS(astrArgs)
ExpandedSubBlockEnd.gif    
End Function

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
Private Function InteractiveGS()Function InteractiveGS() As Boolean
InBlock.gif        
Dim astrArgs(2As String
InBlock.gif        astrArgs(
0= "gs" 'The First Parameter is Ignored
InBlock.gif
        astrArgs(1= "-c"
InBlock.gif        astrArgs(
2= "systemdict /start get exec"
InBlock.gif        
Return CallGS(astrArgs)
ExpandedSubBlockEnd.gif    
End Function

InBlock.gif
InBlock.gif
InBlock.gif    
'------------------------------------------------
InBlock.gif
    'User Defined Functions End
InBlock.gif
    '------------------------------------------------
InBlock.gif

ExpandedSubBlockStart.gifContractedSubBlock.gif    
Sub Main()Sub Main()
InBlock.gif        ConvertFile()
InBlock.gif        
'InteractiveGS()
InBlock.gif
        MsgBox("Done")
ExpandedSubBlockEnd.gif    
End Sub

InBlock.gif
ExpandedBlockEnd.gif
End Module

None.gif
None.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值