Frage

ich habe eine Benutzersteuerung für WinCC (Siemens) (SCADA) geschrieben.Jetzt möchte ich einen Zeiger auf das Steuerelement übergeben.Der einzige Weg, dies zu tun, ist:schreibt den Zeiger auf eine Eigenschaft.

WinCC hat nur diese Methoden, um Eigenschaften festzulegen

  • SetPropBOOL
  • SetPropChar
  • Setpropdoppelt
  • Vorschlag setzen

Die Eigenschaft von control hat UInt als Datentyp und ich verwende die SetPropDouble-Methode, um die Adresse von einem Objekt festzulegen.

WinCC Globales Skript (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 );

Ich habe mein Steuerelement debuggt (Haken am WinCC-Prozess) und sehe, dass dem Eigenschaftensatz ein Adresswert zugewiesen wird, z. B.0x03041080.

Nun die Frage:Wie bekomme ich das Objekt in c # (.Net) auf die Adresse?

Mein Versuch löst eine Ausnahme aus: 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;
        }
    }
}

Okay:ich habe meinen Code geändert, um ihn zu verwenden STRING

WinCC

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

Und c # ist jetzt

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!
    }
}

Andere Erkenntnisse!

Die Adresse aus dem ADO-Objekt befindet sich nicht im Prozessspeicher, der mein Steuerelement aufgerufen hat (Debuggen mit ollydbg).WinCC hat zwei Programme:PDLRT.exe zur Visualisierung (dies ruft mein Steuerelement auf) und SKRIPT.exe zum Ausführen von GLOBAL-SCRIPT (Ansi-C).

Von PDLRT aus habe ich Zugriff auf die Zeigeradresse vom ADO-Objekt.Durch Aufruf von GCHandle in C# der ADO-Objektadresse wird die Ausnahme ausgelöst.(ExecutionEngineException)

War es hilfreich?

Lösung 2

ok,

Vor langer Zeit und ich fragte den Support von Siemens.

Siemens: Die geladenen DLLs, Bedienelemente usw. sind in einem getrennten Speicher laden und nicht in der Anwendung (Haupt-) Speicher.Speicheradresse-Aktie zwischen DLLs, Controls .... funktioniert nicht.Alle haben einen getrennten Speicher.

super.Nur Weg: Rohre oder andere Kommunikationsimplementierungen (TCP / IP, ...).

Andere Tipps

Ich habe keine Ahnung, ob C # über einen Zeiger so auf C ++ zugreifen kann.

Egal, das: (DWORD)(&autoDB) ist falsch, das setzt die adresse des Zeigers als Wert der Immobilie, was sinnlos ist.

Sie benötigen den Wert des Zeigers, dh. (DWORD) autoDB.

Auch, SetPropDouble() akzeptiert einen Wert vom Typ double, also.Fließkommazahlen.Das ist keine sehr gute Möglichkeit, einen Zeiger zu teilen, der eine (große) Ganzzahl ist.Versuchen Sie eine andere Darstellung, String funktioniert möglicherweise, wenn Sie keinen Zugriff auf eine ausreichend große Ganzzahl haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top