免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2636 | 回复: 0
打印 上一主题 下一主题

实现用VB.NET调用Ghostscript的API [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-23 10:58 |只看该作者 |倒序浏览
Option Explicit On
Imports System.Runtime.InteropServices
Module gsapiModule gsapi
Public Declare Sub CopyMemory()Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As IntPtr, ByVal source As IntPtr, ByVal bytes As Long)
'------------------------------------------------
    'UDTs Start
    '------------------------------------------------
    <StructLayout(LayoutKind.Sequential)> Public Structure GS_RevisionStructure GS_Revision
Public strProduct As IntPtr
Public strCopyright As IntPtr
Public intRevision As Integer
Public intRevisionDate As Integer
End Structure
'------------------------------------------------
    'UDTs End
    '------------------------------------------------

'------------------------------------------------
    'Callback Functions Start
    '------------------------------------------------
    'These are only required if you use gsapi_set_stdio
    Public Delegate Function StdioCallBack()Function StdioCallBack(ByVal handle As IntPtr, ByVal strptr As IntPtr, ByVal count As Integer) As Integer
Public Function gsdll_stdin()Function gsdll_stdin(ByVal intGSInstanceHandle As IntPtr, ByVal strz As IntPtr, ByVal intBytes As Integer) As Integer
' This is dumb code that reads one byte at a time
        ' Ghostscript doesn't mind this, it is just very slow
        If intBytes = 0 Then
gsdll_stdin = 0
Else
Dim ich As Integer = Console.Read()
If ich = -1 Then
gsdll_stdin = 0 ' EOF
            Else
Dim bch As Byte = ich
Dim gcByte As GCHandle = GCHandle.Alloc(bch, GCHandleType.Pinned)
Dim ptrByte As IntPtr = gcByte.AddrOfPinnedObject()
CopyMemory(strz, ptrByte, 1)
ptrByte = IntPtr.Zero
gcByte.Free()
gsdll_stdin = 1
End If
End If
End Function
Public Function gsdll_stdout()Function gsdll_stdout(ByVal intGSInstanceHandle As IntPtr, ByVal strz As IntPtr, ByVal intBytes As Integer) As Integer
' If you can think of a more efficient method, please tell me!
        ' We need to convert from a byte buffer to a string
        ' First we create a byte array of the appropriate size
        Dim aByte(intBytes) As Byte
' Then we get the address of the byte array
        Dim gcByte As GCHandle = GCHandle.Alloc(aByte, GCHandleType.Pinned)
Dim ptrByte As IntPtr = gcByte.AddrOfPinnedObject()
' Then we copy the buffer to the byte array
        CopyMemory(ptrByte, strz, intBytes)
' Release the address locking
        ptrByte = IntPtr.Zero
gcByte.Free()
' Then we copy the byte array to a string, character by character
        Dim str As String
Dim i As Integer
For i = 0 To intBytes - 1
str = str + Chr(aByte(i))
Next
' Finally we output the message
        Console.Write(str)
gsdll_stdout = intBytes
End Function
Public Function gsdll_stderr()Function gsdll_stderr(ByVal intGSInstanceHandle As IntPtr, ByVal strz As IntPtr, ByVal intBytes As Integer) As Integer
gsdll_stderr = gsdll_stdout(intGSInstanceHandle, strz, intBytes)
End Function
'------------------------------------------------
    'Callback Functions End
    '------------------------------------------------

'------------------------------------------------
    'API Calls Start
    '------------------------------------------------
    'Win32 API
    'GhostScript API
    '    Public Declare Function gsapi_revision Lib "gsdll32.dll" (ByVal pGSRevisionInfo As IntPtr, ByVal intLen As Integer) As Integer
    Public Declare Function gsapi_revision()Function gsapi_revision Lib "gsdll32.dll" (ByRef pGSRevisionInfo As GS_Revision, ByVal intLen As Integer) As Integer
Public Declare Function gsapi_new_instance()Function gsapi_new_instance Lib "gsdll32.dll" (ByRef lngGSInstance As IntPtr, ByVal lngCallerHandle As IntPtr) As Integer
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
Public Declare Sub gsapi_delete_instance()Sub gsapi_delete_instance Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr)
Public Declare Function gsapi_init_with_args()Function gsapi_init_with_args Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr, ByVal lngArgumentCount As Integer, ByVal lngArguments As IntPtr) As Integer
Public Declare Function gsapi_run_file()Function gsapi_run_file Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr, ByVal strFileName As String, ByVal intErrors As Integer, ByVal intExitCode As Integer) As Integer
Public Declare Function gsapi_exit()Function gsapi_exit Lib "gsdll32.dll" (ByVal lngGSInstance As IntPtr) As Integer
'------------------------------------------------
    'API Calls End
    '------------------------------------------------

'------------------------------------------------
    'User Defined Functions Start
    '------------------------------------------------
    Public Function StringToAnsiZ()Function StringToAnsiZ(ByVal str As String) As Byte()
' Convert a Unicode string to a null terminated Ansi string for Ghostscript.
        ' The result is stored in a byte array.  Later you will need to convert
        ' this byte array to a pointer with GCHandle.Alloc(XXXX, GCHandleType.Pinned)
        ' and GSHandle.AddrOfPinnedObject()
        Dim intElementCount As Integer
Dim intCounter As Integer
Dim aAnsi() As Byte
Dim bChar As Byte
intElementCount = Len(str)
ReDim aAnsi(intElementCount + 1)
For intCounter = 0 To intElementCount - 1
bChar = Asc(Mid(str, intCounter + 1, 1))
aAnsi(intCounter) = bChar
Next intCounter
aAnsi(intElementCount) = 0
StringToAnsiZ = aAnsi
End Function
Public Function AnsiZtoString()Function AnsiZtoString(ByVal strz As IntPtr) As String
' We need to convert from a byte buffer to a string
        Dim byteCh(1) As Byte
Dim bOK As Boolean = True
Dim gcbyteCh As GCHandle = GCHandle.Alloc(byteCh, GCHandleType.Pinned)
Dim ptrByte As IntPtr = gcbyteCh.AddrOfPinnedObject()
Dim j As Integer = 0
Dim str As String
While bOK
' This is how to do pointer arithmetic!
            Dim sPtr As New IntPtr(strz.ToInt64() + j)
CopyMemory(ptrByte, sPtr, 1)
If byteCh(0) = 0 Then
bOK = False
Else
str = str + Chr(byteCh(0))
End If
j = j + 1
End While
AnsiZtoString = str
End Function
Public Function CheckRevision()Function CheckRevision(ByVal intRevision As Integer) As Boolean
' Check revision number of Ghostscript
        Dim intReturn As Integer
Dim udtGSRevInfo As GS_Revision
Dim gcRevision As GCHandle
gcRevision = GCHandle.Alloc(udtGSRevInfo, GCHandleType.Pinned)
intReturn = gsapi_revision(udtGSRevInfo, 16)
Console.WriteLine("Revision = " & udtGSRevInfo.intRevision)
Console.WriteLine("RevisionDate = " & udtGSRevInfo.intRevisionDate)
Console.WriteLine("roduct = " & AnsiZtoString(udtGSRevInfo.strProduct))
Console.WriteLine("Copyright = " & AnsiZtoString(udtGSRevInfo.strCopyright))
If udtGSRevInfo.intRevision = intRevision Then
CheckRevision = True
Else
CheckRevision = False
End If
gcRevision.Free()
End Function
Public Function CallGS()Function CallGS(ByVal astrGSArgs() As String) As Boolean
Dim intReturn As Integer
Dim intGSInstanceHandle As IntPtr
Dim aAnsiArgs() As Object
Dim aPtrArgs() As IntPtr
Dim aGCHandle() As GCHandle
Dim intCounter As Integer
Dim intElementCount As Integer
Dim iTemp As Integer
Dim callerHandle As IntPtr
Dim gchandleArgs As GCHandle
Dim intptrArgs As IntPtr
' Print out the revision details.
        ' If we want to insist on a particular version of Ghostscript
        ' we should check the return value of CheckRevision().
        CheckRevision(704)
' Load Ghostscript and get the instance handle
        intReturn = gsapi_new_instance(intGSInstanceHandle, callerHandle)
If (intReturn < 0) Then
Return (False)
End If
' Capture stdio
        Dim stdinCallback As StdioCallBack
stdinCallback = AddressOf gsdll_stdin
Dim stdoutCallback As StdioCallBack
stdoutCallback = AddressOf gsdll_stdout
Dim stderrCallback As StdioCallBack
stderrCallback = AddressOf gsdll_stderr
intReturn = gsapi_set_stdio(intGSInstanceHandle, stdinCallback, stdoutCallback, stderrCallback)
If (intReturn >= 0) Then
' Convert the Unicode strings to null terminated ANSI byte arrays
            ' then get pointers to the byte arrays.
            intElementCount = UBound(astrGSArgs)
ReDim aAnsiArgs(intElementCount)
ReDim aPtrArgs(intElementCount)
ReDim aGCHandle(intElementCount)
For intCounter = 0 To intElementCount
aAnsiArgs(intCounter) = StringToAnsiZ(astrGSArgs(intCounter))
aGCHandle(intCounter) = GCHandle.Alloc(aAnsiArgs(intCounter), GCHandleType.Pinned)
aPtrArgs(intCounter) = aGCHandle(intCounter).AddrOfPinnedObject()
Next
gchandleArgs = GCHandle.Alloc(aPtrArgs, GCHandleType.Pinned)
intptrArgs = gchandleArgs.AddrOfPinnedObject()
callerHandle = IntPtr.Zero
intReturn = gsapi_init_with_args(intGSInstanceHandle, intElementCount + 1, intptrArgs)
' Release the pinned memory
            For intCounter = 0 To intElementCount
aGCHandle(intCounter).Free()
Next
gchandleArgs.Free()
' Stop the Ghostscript interpreter
            gsapi_exit(intGSInstanceHandle)
End If
' release the Ghostscript instance handle
        gsapi_delete_instance(intGSInstanceHandle)
If (intReturn >= 0) Then
CallGS = True
Else
CallGS = False
End If
End Function
Private Function ConvertFile()Function ConvertFile() As Boolean
Dim astrArgs(10) As String
astrArgs(0) = "ps2pdf" 'The First Parameter is Ignored
        astrArgs(1) = "-dNOPAUSE"
        astrArgs(2) = "-dBATCH"
        astrArgs(3) = "-dSAFER"
        astrArgs(4) = "-r300"
        astrArgs(5) = "-sDEVICE=pdfwrite"
        astrArgs(6) = "-sOutputFile=c:\out.pdf"
        astrArgs(7) = "-c"
        astrArgs( = ".setpdfwrite"
        astrArgs(9) = "-f"
        astrArgs(10) = "c:\gs\gs7.04\examples\colorcir.ps"
        Return CallGS(astrArgs)
End Function
Private Function InteractiveGS()Function InteractiveGS() As Boolean
Dim astrArgs(2) As String
astrArgs(0) = "gs" 'The First Parameter is Ignored
        astrArgs(1) = "-c"
        astrArgs(2) = "systemdict /start get exec"
        Return CallGS(astrArgs)
End Function
'------------------------------------------------
    'User Defined Functions End
    '------------------------------------------------

Sub Main()Sub Main()
ConvertFile()
'InteractiveGS()
        MsgBox("Done"
End Sub
End Module
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP