¿Cómo puedo obtener un objeto del puntero de dirección
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)
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.