none
如何透過網路或RS232傳送API command RRS feed

  • 問題

  • 各位前備:

    小弟有一設備可以由網路或RS232連接,不過廠商只給一個dll檔與一個電子文件,文件裡說明了三個API command如Device_Initial、Device_IO_Control、Device_Close‧關鍵是我怎麼對設備下這些API command呢?以前是有遇到類似的設備,我可以用Socket元件連上後,跟據廠商給的命令格式,製作成一小封包網路傳輸控制設備。此次廠商給的這API command有點類似win32 API但是我卻不知道如何傳給設備?
    請各位幫忙尋求答案~~謝謝!!

    2010年9月9日 上午 08:35

解答

  • 通常的情況是廠商給的API中的Initial就會初始化RS232或網路或任何應該要接到這設備的連線裝置. 我覺得應該看一下 DevInfo 這個資料型態的內容

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    • 已標示為解答 chihwing 2010年9月15日 上午 03:09
    2010年9月9日 下午 11:21
    版主

所有回覆

  • 是什麼廠商設備?文件可上傳到如Sky Drive等網路空間嗎...
    2010年9月9日 上午 09:41
  • 整份文件都在講這3個command

    Function InitialDevice(DevInfo : Pointer; Msg : Pointer ; Len : Pointer): Boolean;stdcall;export;

    (DevInfo自訂資料型態主要是回傳回來的硬體資訊,Msg :Device傳回來的ERROR CODE,Len:Msg長度)

    Procedure ClosDevice;stdcall;export;

    Function DeviceIOControl (Fun , DeviceID , iPort , iBuzzType:Byte ; pBuf:Pointer ; pLen : Pointer):Byte;stdcall;export

    首先我要送InitialDevice初始化或open設備,接下來才有可能做IO控制.

    不過一開始我就不知道怎麼透過網路去送這個command了,是不是還有什麼Driver沒給我呢??

     

    2010年9月9日 上午 10:37
  • 請直接跟廠商要 sample 。
    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2010年9月9日 下午 01:14
  • 通常的情況是廠商給的API中的Initial就會初始化RS232或網路或任何應該要接到這設備的連線裝置. 我覺得應該看一下 DevInfo 這個資料型態的內容

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    • 已標示為解答 chihwing 2010年9月15日 上午 03:09
    2010年9月9日 下午 11:21
    版主
  • 我終於弄清楚怎麼下command給設備了

    1. 如同Bill Chung前備所述,Initial command的DevInfo是設備的回傳資訊
    2. 跟據Devinfo回傳的資料,我再執行DeviceIO去傳送我要控制設備的command

    下面是DevInfo的型態

    DeviceInfo=record
    aName :Array [0..9] of byte;
    iNameLen:byte;
    iDeviceNum :byte;
    iPortNum :byte;
    aPortInfo:array[1..iPortNum] of PortInfo;
    End;

    portInfo=record
    iNO:byte;
    aName :Array[0..19] of byte;
    iNameLen:byte;
    iMaxLen:Integer;
    iType:byte;
    End;

    接下來我要如何把它轉成VB.net語法,且分配記憶體給它(是不是unmanaged Marshal物件的使用?),然後將指標位置傳給InitialDevice?

    2010年9月14日 上午 06:35
  • 看起來很是Delphi 的結構宣告 (Sorry, 我對Delphi沒啥涉獵, 只是覺得應該是這樣)

    所以你要先宣告兩個結構, DeviceInfo 和 PortInfo. 試著用ByRef 傳入.

    細節你可能需要問熟Delphi的人, 因為我也搞不懂 :pointer 這在Delphi代表什麼意義.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    2010年9月14日 上午 06:50
    版主
  • 目前已經能取回設備部份參數

    我的程式作法:

    加入一個類別
    <StructLayout(LayoutKind.Sequential)> _
    Public Class TportInfo
      Dim iNo As Byte
      Dim aName(19) As Byte
      Dim iNameLen As Byte
      Dim iMaxLen As Integer
      Dim iType As Byte
    End Class
    <StructLayout(LayoutKind.Sequential)> _
    Public Class TdeviceInfo
      Dim aName(9) As Byte
      Dim iNameLen As Byte
      Dim iDeviceNum As Byte
      Dim iPortNum As Byte
      Public iPortInfo As IntPtr
      '本來要宣告Dim iPortInfo(11) As TportInfo 
      '但是在Marshal.StructureToPtr(DCT_Device_Info, pDevInfo, 
      'True)會出現錯誤 
    End Class
    Public Class DeviceClass
    
    
      <DllImport("dcs.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Shared Function InitialDCS _
    (ByVal pDEVInfo As IntPtr, _
     ByVal pMsg As IntPtr, _
     ByRef pLen As Int32) _
    As Boolean
      End Function
    
      <DllImport("dcs.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
      Shared Function CloseDCS() As Boolean
      End Function
    End Class
    
    啟動設備程式
    Private Sub DeviceConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeviceConnect.Click
        Dim DCT_Device_Info As New TdeviceInfo
        Dim pDevInfo As IntPtr
        Dim pMsg(65535) As Byte
        Dim MsgPointer As IntPtr
        Dim pLen As Int32 = 0
        MsgPointer = Marshal.AllocHGlobal(65536)
        Marshal.Copy(pMsg, 0, MsgPointer, 65536)
        pDevInfo = Marshal.AllocHGlobal(Marshal.SizeOf(DCT_Device_Info))
    
        Marshal.StructureToPtr(DCT_Device_Info, pDevInfo, True)
        Dim result As Boolean = DeviceClass.InitialDCS(pDevInfo, MsgPointer, pLen)
    
        Dim retmsg(pLen) As Byte
        For i As Int16 = 0 To pLen
          retmsg(i) = Marshal.ReadByte(MsgPointer, i)
        Next
        Dim DCTMessage As String = Encoding.Default.GetString(retmsg)
        Dim DeviceName(9) As Byte
        For i As Integer = 0 To 9
          DeviceName(i) = Marshal.ReadByte(pDevInfo, i)
        Next
        Dim DeviceNameString As String = Encoding.Default.GetString(DeviceName)
        Dim DeviceNumber As String = Marshal.ReadByte(pDevInfo, 11)
        Dim DevicePortNumber As String = Marshal.ReadByte(pDevInfo, 12)
    
        Marshal.FreeHGlobal(MsgPointer)
        Marshal.FreeHGlobal(pDevInfo)
        DeviceClass.CloseDCS()
      End Sub
    DeviceNameString,DeviceNumber,DevicePortNumber參數傳回都是正確
    請問各位前輩,我該怎麼取得iPortInfo的內容呢?這樣子的宣告好像沒有事先分配記憶體給iportInfo?我也嘗試這樣宣告
    <StructLayout(LayoutKind.Sequential)> _
    Public Class TdeviceInfo
        Dim aName(9) As Byte
        Dim iNameLen As Byte
        Dim iDeviceNum As Byte
        Dim iPortNum As Byte
        Public iPortInfo(11) As TportInfo
        Sub New()
            For i As Integer = 0 To 11
                iPortInfo(i) = New TportInfo
            Next
        End Sub
    End Class這樣子也不行Marshal.StructureToPtr(DCT_Device_Info, pDevInfo, True)也會錯誤
    所以現在問題是我不知道傳回iPortInfo??
    感謝各位前輩幫忙,這地方真的幫助好多喔~~ 
     
     
    2010年9月14日 上午 11:03
  • 現在已經可以完全取回設備參數,在結構定義時,事先指定其大小

    結構定義:
    
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure TportInfo
      Dim iNo As Byte
      <MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)> _
      Dim aName() As Byte
      Dim iNameLen As Byte
      Dim iMaxLen As Integer
      Dim iType As Byte
    End Structure
    
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure TdeviceInfo
    
      <MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)> _
      Dim aName() As Byte
      Dim iNameLen As Byte
      Dim iDeviceNum As Byte
      Dim iPortNum As Byte
      <MarshalAs(UnmanagedType.ByValArray, SizeConst:=12)> _
      Dim iPortInfo() As TportInfo
    End Structure
    
    Public Class DeviceClass
    
    
      <DllImport("dcs.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Shared Function InitialDCS _
    (ByVal pDEVInfo As IntPtr, _
     ByVal pMsg As IntPtr, _
     ByRef pLen As Int32) _
    As Boolean
      End Function
    
      <DllImport("dcs.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
      Shared Function CloseDCS() As Boolean
      End Function
    
    
    End Class
    
    啟動設備&傳回參數:
    
    
    Dim DCT_Device_Info As New TdeviceInfo
        Dim pDevInfo As IntPtr
        Dim pMsg(65535) As Byte
        Dim MsgPointer As IntPtr
        Dim pLen As Int32 = 0
        MsgPointer = Marshal.AllocHGlobal(65536)
        Marshal.Copy(pMsg, 0, MsgPointer, 65536)
    
        pDevInfo = Marshal.AllocHGlobal(Marshal.SizeOf(DCT_Device_Info))
    
        Marshal.StructureToPtr(DCT_Device_Info, pDevInfo, True)
        Dim result As Boolean = DeviceClass.InitialDCS(pDevInfo, MsgPointer, pLen)
    
        Dim retu As TdeviceInfo = CType(Marshal.PtrToStructure(pDevInfo, GetType(TdeviceInfo)), TdeviceInfo)
    
    

    retu即設備傳回來的參數~~~~

    感謝各位前輩鼎力相助~~~謝謝囉~~~~

    2010年9月15日 上午 03:08