Pregunta

he escrito un control de usuario de WinCC (Siemens) (SCADA).Ahora quiero pasar un puntero a la de control.La única manera de hacer esto es:escribir el puntero a una propiedad.

WinCC sólo tiene este método para establecer las propiedades

  • SetPropBOOL
  • SetPropChar
  • SetPropDouble
  • SetPropWord

La propiedad de control ha UInt como tipo de datos y uso de los SetPropDouble método para establecer la dirección de un objeto.

WinCC Global Script (ANSI-C)

//autoDB is an ADODB.Connection object
//object* autoDB = __object_create("ADODB.Connection");
extern __object* autoDB;
//SetPropDouble( "PictureName", "ControlName", "PropertyName", (DWORD)(&autoDB) );
SetPropDouble( "PictureName", "ControlName", "PropertyName", (DWORD)autoDB );

He de depuración de mi control (gancho en WinCC-proceso) y veo que el conjunto de propiedades se le asigne una dirección de valor-por ejemplo,0x03041080.

Ahora la pregunta:¿Cómo puedo obtener el objeto en c# (.Net) en la dirección?

Mi pruebe lanza una excepción: ExecutionEngineException

private ADODB.Connection _database;
private IntPtr _ptr = IntPtr.Zero;

public uint DataBase{
    get{
        return (uint)_ptr;
    }
    set{
        if( value != 0 ){
            _ptr = (IntPtr)value;
            GCHandle gH = GCHandle.FromIntPtr(_ptr); // THIS LINE THROW THE EXCEPTION
            _database = gH.Target;
        }
    }
}

Ok:he cambiado mi código para utilizar STRING

WinCC

extern __object* autoDB;
DWORD addr = (DWORD)autoDB;
char sAddr[11];
sprintf( sAddr, "%d\0", addr );
SetPropChar( "PictureName", "ControlName", "DataBaseAddr", sAddr );

Y c# es ahora

private string _lpszDataBaseAddr = "";
public string DataBaseAddr{
    get{
        return _lpszDataBaseAddr;
    }
    set{
        uint addr;
        bool ret = uint.TryParse( value, out addr );
        if( ! ret ){
            return;
        }
        IntPtr ptr = (IntPtr)addr;
        GCHandle gH = GCHandle.FromIntPtr( ptr );  // THE SAME ERROR!
    }
}

Otros hallazgos!

La dirección de la ADO-Objeto no está en el proceso de la memoria que llamó mi control (depuración con ollydbg).WinCC dispone de dos programas:PDLRT.exe para la visualización (esto es llamando a mi control) y SCRIPT.exe para el funcionamiento GLOBAL-SCRIPT (Ansi-C).

De PDLRT, he acceso al puntero-dirección de ADO-Objeto.Por llamar GCHandle en C# de la ADO-objeto-dirección, se produce la excepción.(ExecutionEngineException)

¿Fue útil?

Solución 2

Ok,

hace mucho tiempo y he pedimos el apoyo de Siemens.

Siemens:La Dll de carga, Controles y así sucesivamente se carga en una separada de la memoria y no en la aplicación (principal) de la memoria.Dirección de memoria Compartido entre Dll, Controles ....no está funcionando.Todos se han separado de la memoria.

Super.Sólo manera:Tuberías u otras implementaciones de comunicación (TCP/IP, ...).

Otros consejos

No tengo idea de si C # puede acceder a través de un puntero en C ++ así.

Independientemente, esto: (DWORD)(&autoDB) es incorrecto, que pone la dirección del puntero como el valor de la propiedad, que es inútil.

Necesita el valor del puntero, es decir, (DWORD) autoDB.

Además, SetPropDouble() acepta un valor del tipo double, es decir, un número de punto flotante.Eso no será una forma muy agradable de compartir un puntero, que es un entero (grande).Pruebe una representación diferente, la cadena podría funcionar si no tiene acceso a un entero lo suficientemente grande.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top