theskiguy Ответов: 2

VB.net Вложенные Структуры


Во - первых, это мой первый пост здесь, так что я надеюсь, что я разместил это правильно. Я много раз использовал этот сайт, чтобы найти ответы на другие вопросы, но мне никогда раньше не приходилось публиковать вопрос.

У меня есть VB.net программа, которую я использую для связи с контроллером Fanuc CNC с интерфейсом ПК, используя библиотеки Fanuc Focas. Контроллер ЧПУ Fanuc управляет работой станка, который используется для резки металлических деталей. Контроллер Fanuc имеет ряд макропеременных, используемых для хранения числовых значений. В настоящее время я могу вызывать различные функции Fanuc для чтения и записи одной переменной одновременно.
Мой VB.net в настоящее время программа считывает несколько макропеременных одновременно с помощью таймера, поэтому я хотел бы ограничить количество звонков, которые я делаю в Fanuc. Я заметил, что Fanuc также предлагает другую функцию, которая может быть использована либо для чтения, либо для записи ряда переменных одновременно. Я пытался заставить эту функцию работать, но мне не везло.

В документации, которую я получил от Fanuc, есть пример, но он выглядит так, как будто написан на C++. Я позвонил в техническую поддержку в Fanuc, и они предоставили мне несколько файлов примеров VB, которые выглядят так, как будто они были написаны в коде до VB6
Основываясь на всей этой информации, я создал следующий код. Структура, которую использует FANUC для этой функции, имеет вложенную структуру, и я никогда раньше не делал ничего подобного. Я попробовал написать вложенную структуру 2 способами. В Примере C++ я показал вложенную структуру, определенную в первичной структуре. Пример VB3 показал вложенную структуру как свою собственную структуру, которая вызывается первичной структурой. Оба способа не сработали. Я думаю, что это то, где у меня есть моя проблема, потому что другие функции, которые я использовал для чтения/записи отдельных переменных, не являются вложенными. Ниже приведен пример кода, который я использую:

Сооружения:
<StructLayout(LayoutKind.Sequential, Pack:=4)> _
    Public Structure IODBMR
        Public datano_s As Short  ' start macro number 
        Public dummy As Short     ' dummy 
        Public datano_e As Short  ' end macro number 
        Public data() As IODBMR_data ' data
    End Structure
   
 <StructLayout(LayoutKind.Sequential,Pack:=4)> _
    Public Structure IODBMR_data
        Public mcr_val As Integer ' macro variable 
        Public dec_val As Short   ' decimal point 
    End Structure


вызов функции:
' read custom macro variables(area specified)
   Declare Function cnc_rdmacror Lib "FWLIB32.DLL" _
       ( ByVal FlibHndl As Integer, ByVal a As Short, ByVal b As Short, ByVal c As Short, ByRef d As IODBMR ) As Short


Код для чтения 5 переменных одновременно:

Private Sub BtnReadMacroRange_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnReadMacroRange.Click
        'Read a series of 5 variables from the Fanuc
        'StartVar = start macro variable number which is input via the GUI
        'End Var = ending macro variable number which is input via the GUI
        'Length = length of structure which is input via the GUI
        Try
            Dim StartVar As Integer = CInt(Me.TxtStartVar.Text)
            Dim EndVar As Integer = CInt(Me.TxtEndVar.Text)
            Dim Length As Integer
            Dim McrVal As Integer
            Dim DecVal As Integer
            Dim VariableNumber As Integer
            Dim Result As String = Nothing
            Dim MacroRange As New Focas1.IODBMR
            Length = CInt(Me.TxtReadMacroRangeLength.Text)

            'Call the Fanuc Function
            'FlibHndl needs to be obtained first
            nRet = Focas1.cnc_rdmacror(FlibHndl, StartVar, EndVar, Length, MacroRange)
            'MsgBox("FlibHndl = " & FlibHndl)
            TextBox1.Text = CStr(nRet)
            'Read the result of a single variable and write the info to the GUI
            For x As Integer = 0 To 4
                VariableNumber = StartVar + x
                McrVal = MacroRange.data(x).mcr_val
                DecVal = MacroRange.data(x).dec_val
                If McrVal = 0 And DecVal = -1 Then
                    Result = "Null"
                Else
                    Result = McrVal * 10 ^ -(DecVal)
                End If

                Select Case x
                    Case 0
                        Me.LblReadMacroRangeResult1.Text = VariableNumber
                        Me.TxtReadMacroRangeResult1.Text = Result
                    Case 1
                        Me.LblReadMacroRangeResult2.Text = VariableNumber
                        Me.TxtReadMacroRangeResult2.Text = Result
                    Case 2
                        Me.LblReadMacroRangeResult3.Text = VariableNumber
                        Me.TxtReadMacroRangeResult3.Text = Result
                    Case 3
                        Me.LblReadMacroRangeResult4.Text = VariableNumber
                        Me.TxtReadMacroRangeResult4.Text = Result
                    Case 4
                        Me.LblReadMacroRangeResult5.Text = VariableNumber
                        Me.TxtReadMacroRangeResult5.Text = Result
                End Select
            Next
        Catch ex As Exception
            MsgBox(ex.Message.ToString)
        End Try
    End Sub

Когда я пытаюсь запустить этот код, все приложение выходит из строя и выдает мне страшное "извините за ошибку inconvience", несмотря на то, что код завернут в try/catch. Я работал с техниками в Fanuc, но у них, похоже, не так много людей, которые много знают о VB.net. Может ли кто-нибудь найти что-нибудь, что я делаю неправильно?

Спасибо,

Simon_Whale

Если вы пройдете через код, где будет ошибка?

Kschuler

Если вы добавите событие UnhandledException к событиям приложения, вы сможете получить дополнительную информацию об ошибке. Смотрите здесь, как это сделать:
http://msdn.microsoft.com/en-us/library/3a02k5s0(v=против 90).aspx

2 Ответов

Рейтинг:
11

s.ralev

Привет, вот мой пример:

Imports System
Imports System.Runtime.InteropServices
Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim odbm1 As New ODBM
        Dim IODBMR1 As New IODBMR
        Dim ret As Short
        Dim hndl As Integer
        cnc_allclibhndl(hndl)
        'Read a single variable from Fanuc
        'Start = 500
        'Length = 10
        ret = cnc_rdmacro(hndl, 500, 10, odbm1)
        If ret = 0 Then
            Label1.Text = odbm1.mcr_val.ToString
        Else
            Label1.Text = "ERR: " & ret.ToString
        End If
        'Read a series of 5 variables from Fanuc
        'Start = 500
        'End   = 505
        'Length = 8+8*6
        ret = cnc_rdmacror(hndl, 500, 505, 56, IODBMR1)
        If ret = 0 Then
            Label2.Text = IODBMR1.data.data1.mcr_val
        Else
            Label2.Text = "ERR: " & ret.ToString
        End If
    End Sub
    <structlayout(layoutkind.sequential,> _
   Public Structure ODBM
        Public datano As Short    ' variable number 
        Public dummy As Short     ' dummy 
        Public mcr_val As Integer ' macro variable 
        Public dec_val As Short   ' decimal point 
    End Structure
    <structlayout(layoutkind.sequential,> _
    Public Structure IODBMR_data
        Public mcr_val As Integer ' macro variable 
        Public dec_val As Short   ' decimal point 
    End Structure
    <structlayout(layoutkind.sequential,> _
    Public Structure ODBMVINF
        Public use_no1 As Short
        Public use_no2 As Short
    End Structure
    <structlayout(layoutkind.sequential,> _
    Public Structure IODBMR1
        Public data1 As IODBMR_data
        Public data2 As IODBMR_data
        Public data3 As IODBMR_data
        Public data4 As IODBMR_data
        Public data5 As IODBMR_data
    End Structure  ' In case that the number of data is 5 

    <structlayout(layoutkind.sequential,> _
  Public Structure IODBMR
        Public datano_s As Short  ' start macro number 
        Public dummy As Short     ' dummy 
        Public datano_e As Short  ' end macro number 
        Public data As IODBMR1
    End Structure
    Declare Function cnc_rdmacro Lib "Fwlib64.dll" _
       (ByVal FlibHndl As Integer, ByVal a As Short, ByVal b As Short, ByRef c As ODBM) As Short
    Declare Function cnc_rdmacror Lib "Fwlib64.dll" _
       (ByVal FlibHndl As Integer, ByVal a As Short, ByVal b As Short, ByVal c As Short, ByRef d As IODBMR) As Short
    Declare Function cnc_allclibhndl Lib "FWLIB64.DLL" _
        (ByRef FlibHndl As Integer) As Short
End Class


theskiguy

Это сработало, мне просто нужно было использовать Fwlib32.dll скорее всего, тогда FwLib64.dll в вызове функции. Вы должны быть на более новом контроллере, чем Fanuc F150i. Единственная проблема, которую я получил, заключается в том, что структура IODBMR1 должна быть жестко закодирована на количество переменных, которые вы хотите прочитать. В приведенном выше примере структура IODBMR1 настроена на чтение 5 переменных, поскольку она содержит 5 структур IODBMR_data. Что мне делать, если я хочу прочитать 10 переменных один раз и 50 переменных в следующий раз? Есть ли способ закодировать структуру IODBMR1 так, чтобы она могла содержать случайное количество структур IODBMR_data?

Спасибо,

muhamad yudy

Привет Сэр,
Я попробовал способ связи с моделью Fanuc I16i, и кодировка, которую я сделал, была неправильной. если сэр разрешит поделиться со мной источником проекта.
Мухаммад.yudy084@gmail.com

s.ralev

Извините за мой поздний ответ. Конечно вы можете создать структуру массива:
Общественная структура IODBMR1
Публичные данные() Как IODBMR_data
Торцевая Конструкция

где-то в коде:

Оператор redim IODBMR1.сведения(П) ' N-количество переменных макро-читать

Рейтинг:
0

TrustTheMath

Может быть, мой ум растет, но где определяется "Focas1"? Вы оформляете импорт где - то еще?


theskiguy

Структура и вызов функции находятся в открытом классе, называемом FOCAS1. Извините, что я не включил это в свой первоначальный пост.

Я также попытался добавить необработанное событие исключения в мои события приложения, но я все еще получаю "извините за ошибку inconvience"