Como posso obter um objeto a partir do ponteiro de endereço
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)
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.