Question

j'ai écrit un contrôle utilisateur pour WinCC (Siemens) (SCADA).Maintenant je veux passer un pointeur vers le contrôle.La seule façon de le faire est:écrire le pointeur à une propriété.

WinCC a des méthodes pour définir les propriétés

  • SetPropBOOL
  • SetPropChar
  • SetPropDouble
  • SetPropWord

La propriété de contrôle a UInt que le type de données et j'utilise le SetPropDouble méthode pour définir l'adresse d'un objet.

WinCC Script Global (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 );

J'ai debug de mon contrôle (crochet sur WinCC-processus) et je vois le bien-set est affecté d'une adresse valeur par ex.0x03041080.

Maintenant, la question:Comment puis-je obtenir l'objet en c# (.Nette) sur l'adresse?

J'essaie déclenche une exception: 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:j'ai changé mon code à utiliser STRING

WinCC

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

Et c# est maintenant

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

Les autres résultats!

L'adresse de l'ADO-Objet n'est pas dans le processus de la mémoire qui a appelé mon contrôle (debug avec ollydbg).WinCC a deux programmes:PDLRT.exe pour la visualisation (c'est l'appel de mon contrôle) et SCRIPT.exe pour l'exécution GLOBAL-SCRIPT (Ansi-C).

De PDLRT, j'ai accès au pointeur d'adresse à partir d'ADO-Objet.Par appel GCHandle en C# de l'ADO-objet, l'adresse, l'exception est levée.(ExecutionEngineException)

Était-ce utile?

La solution 2

OK,

Il y a longtemps et j'ai demandé au soutien de Siemens.

Siemens: Les DLL chargées, les commandes, etc. sont chargées dans une mémoire séparée et non dans la mémoire de l'application (principale).Adresse mémoire-partage entre DLL, contrôles .... ne fonctionne pas.Tous ont une mémoire séparée.

super.Seulement: des tuyaux ou d'autres implémentations de communication (TCP / IP, ...).

Autres conseils

Je n'ai aucune idée si C# peuvent accéder par l'intermédiaire d'un pointeur en C++ comme ça.

Peu importe, ceci: (DWORD)(&autoDB) a tort, qui met l' adresse du pointeur comme la valeur de la propriété, ce qui est inutile.

Vous avez besoin de la valeur du pointeur, c'est à dire (DWORD) autoDB.

Aussi, SetPropDouble() accepte une valeur de type double, c'est à direun nombre à virgule flottante.Qui ne seront pas d'une très belle façon de partager un pointeur, ce qui est un (grand) nombre entier.Essayez différents représentation, la chaîne pourrait fonctionner si vous n'avez pas accès à un assez grand nombre entier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top