Pergunta

eu tenho escrito um controle de usuário para o WinCC (Siemens) (SCADA).Agora eu quero passar um ponteiro para o controle.A única maneira de fazer isso é:escreva o ponteiro para uma propriedade.

WinCC tem apenas esta métodos para definir propriedades

  • SetPropBOOL
  • SetPropChar
  • SetPropDouble
  • SetPropWord

A propriedade de controle tem como tipo de dados UInt e eu uso o SetPropDouble método para definir o endereço de um objeto.

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

Eu depuração do meu controle (gancho no WinCC-processo) e vejo a propriedade de conjunto se torna um endereço atribuído valor e.g.0x03041080.

Agora a pergunta:Como posso obter o objeto em c# (.Net) em que o endereço?

Minha tente lança uma exceção: 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:eu mudei o meu código para usar STRING

WinCC

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

E c# agora é

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

Outros achados!

O endereço do ADO-o Objeto não está no processo de memória que chamou minha controle (debug com o ollydbg).WinCC tem dois programas:PDLRT.exe para visualização (este é o chamado do meu controle) e SCRIPT.exe para a execução GLOBAL do SCRIPT (Ansi-C).

A partir de PDLRT, eu tenho acesso ao ponteiro de endereço a partir do ADO-Objeto.A chamada GCHandle em C# do ADO-objeto-endereço, a exceção é lançada.(ExecutionEngineException)

Foi útil?

Solução 2

Ok,

há muito tempo atrás e eu a pedir o apoio de Siemens.

Siemens:As Dlls carregadas, Controles e etc, são de carga em um separadas de memória e não no aplicativo (principal) de memória.Endereço de memória-Share entre Dlls, Controles ....não está funcionando.Todos têm uma separada da memória.

Super.Só maneira:Tubos ou outras implementações de comunicação (TCP/IP, ...).

Outras dicas

Eu não tenho idéia se a C# pode acessar através de um ponteiro em C++ assim.

De qualquer forma, esta: (DWORD)(&autoDB) é errado, o que coloca o endereço do ponteiro como o valor da propriedade, o que é inútil.

Você precisa o valor do ponteiro, isto é, (DWORD) autoDB.

Também, SetPropDouble() aceita um valor do tipo double, i.é.um número de ponto flutuante.Que não será uma maneira muito agradável para compartilhar um ponteiro, o que é um (grande) inteiro.Tente algo diferente para representação de seqüência de caracteres podem funcionar se você não tem acesso a um grande o suficiente inteiro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top