Problema con estructuras

Iniciado por puribamber, 14 Agosto 2014, 13:06 PM

0 Miembros y 1 Visitante están viendo este tema.

puribamber

Hola amigos del foro!
Aunque nunca he escrito nada por aquí, he leido bastantes artíclos que me han sido de gran ayuda.

Ahora me encuentro con un problema que se escapa a mi lógica: Tengo una estructura que he creado, con dos instancias a la misma (cam y hmicam). Una sirve para almacenar los datos (cam) y la otra para mostrarlos (hmicam) de forma que cuando se muestran (en un listview) paso los valores de cam a hmicam y muestro esos últimos. En el listview se pueden modificar (sobre hmi cam) y al cerrar la aplicación quiero que se asigne de forma inversa para guardar cam.

Lo q me pasa es que al cambiar un valor de la estructura hmicam, también se cambia en cam!!!

Tengo entendido que, al ser dos instancias diferentes, son como dos variables diferentes, no?

Qué hago!?!?!

Las estructuras son estas:

  'STRUCTURES
    <Serializable()> Public Structure stData
        Public Name As String
        Public Value As Double
        Public Enabled As Boolean
        'public Description as string
    End Structure

    <Serializable()> Public Structure stCam
        Public Name As String
        Public Index As Integer
        Public CamType As enumCamType
        Public Enabled As Boolean
        Public Calibrate As Boolean
        Public CalibOK As Boolean
        Public Running As Boolean
        Public Param() As stData
        Public Setting() As stData
        Public Work() As stData
    End Structure

Las instancias:

Public Cam() As stCam
Public HmiCam() As stCam

En la inicialización del listview hago:
HmiCam = Cam

y después escribo en HmiCam(indice).Work(subindice).Value.
cuando lo hago también cambia el valor en Cam(indice).Work(subindice).Value.

Muchas gracias por adelantado...

puribamber

He probado diferentes ñapas (comentar código, quitar asignaciones...) y continúa haciendo esa 'doble asignación'...

A nadie se le ocurre nada?

vladek

#2
Creo que acá el problema está en la asignación que estás haciendo.
Al asignar dos array así "A = B" es como asignar un puntero de B a A.
Por qué no probás con el método CLONE de los array?

Hace bastante que no toco este tema en vb (desde que tenemos List xD) pero sería algo como

HmiCam = Cam.Clone()

El tema tiene que estar por ahí.

PD: Qué datos ves que cambian? Absolutamente todos? Probaste cambiar por ejemplo, Name o Enabled a ver si esos se reflejan en la otra variable?
Desconfío de esos tipos definidos por el usuario, se me hace a puntero.

Saludos.

puribamber

He probado cambiando también .Enabled y también se cambia en las dos estructuras...
También he probado con HmiCam = Cam.Clone() y continúa pasando igual...

vladek

El problema es el siguiente.
La asignación que estás haciendo se llama Shallow Copy, y al querer copiar un vector, estás copiando en definitiva la referencia al mismo. Estás creando un puntero. Podés ahondar más en el tema en la web, no recuerdo mucho de esto.
Me parece que si el vector es de tipos de datos nativos (String, Boolean), lo copia sin problemas. Pero al ser de un tipo creado por vos, surge esto.

Necesitas hacer lo que se denomina un Deep Copy, esto es, recorrer con un FOR (o for each) el array del que quieres copiar, y asignar índice por índice al segundo.

Ejemplo:

Dim a(1) As MiEstruct
Dim b(1) As MiEstruct

b = a

NO FUNCIONA

b(0) = a(0)

SI FUNCIONA.

puribamber

Ya está!!!!!!!!!!!

Era el tema del deep copy que comentaba el compañero vladek.

al final he hecho una función para asignar, tal que así:

Public Function copyCam(ByVal hmi2cam As Boolean) As Boolean
        For i As Integer = 0 To MAX_CAM
            If hmi2cam Then
                Cam(i).Name = HmiCam(i).Name
                Cam(i).Index = HmiCam(i).Index
                Cam(i).CamType = HmiCam(i).CamType
                Cam(i).Enabled = HmiCam(i).Enabled
                Cam(i).Calibrate = HmiCam(i).Calibrate
                Cam(i).CalibOK = HmiCam(i).CalibOK
                Cam(i).Running = HmiCam(i).Running
                For j As Integer = 0 To MAX_DATA_PARAM
                    Cam(i).Param(j).Enabled = HmiCam(i).Param(j).Enabled
                    Cam(i).Param(j).Name = HmiCam(i).Param(j).Name
                    Cam(i).Param(j).Value = HmiCam(i).Param(j).Value
                Next
                For j As Integer = 0 To MAX_DATA_SET
                    Cam(i).Setting(j).Enabled = HmiCam(i).Setting(j).Enabled
                    Cam(i).Setting(j).Name = HmiCam(i).Setting(j).Name
                    Cam(i).Setting(j).Value = HmiCam(i).Setting(j).Value
                Next
                For j As Integer = 0 To MAX_DATA_WORK
                    Cam(i).Work(j).Enabled = HmiCam(i).Work(j).Enabled
                    Cam(i).Work(j).Name = HmiCam(i).Work(j).Name
                    Cam(i).Work(j).Value = HmiCam(i).Work(j).Value
                Next
            Else
                HmiCam(i).Name = Cam(i).Name
                HmiCam(i).Index = Cam(i).Index
                HmiCam(i).CamType = Cam(i).CamType
                HmiCam(i).Enabled = Cam(i).Enabled
                HmiCam(i).Calibrate = Cam(i).Calibrate
                HmiCam(i).CalibOK = Cam(i).CalibOK
                HmiCam(i).Running = Cam(i).Running
                For j As Integer = 0 To MAX_DATA_PARAM
                    HmiCam(i).Param(j).Enabled = Cam(i).Param(j).Enabled
                    HmiCam(i).Param(j).Name = Cam(i).Param(j).Name
                    HmiCam(i).Param(j).Value = Cam(i).Param(j).Value
                Next
                For j As Integer = 0 To MAX_DATA_SET
                    HmiCam(i).Setting(j).Enabled = Cam(i).Setting(j).Enabled
                    HmiCam(i).Setting(j).Name = Cam(i).Setting(j).Name
                    HmiCam(i).Setting(j).Value = Cam(i).Setting(j).Value
                Next
                For j As Integer = 0 To MAX_DATA_WORK
                    HmiCam(i).Work(j).Enabled = Cam(i).Work(j).Enabled
                    HmiCam(i).Work(j).Name = Cam(i).Work(j).Name
                    HmiCam(i).Work(j).Value = Cam(i).Work(j).Value
                Next
            End If
        Next

        Return True
    End Function

Es un rollazo impresionante ya que ahora tengo que tener en cuenta esta función cada vez que agregue/quite miembros de la estructura.
Pero bueno, así ya está solucionado...  :D

engel lex

usa etiquetas GeSHi al colocar codigo

si necesitas agregar información no hagas 2 posts seguidos, sino que modifica el ultimo
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.