我怎么能得到一个对象从指针地址

本文关键字:指针 地址 一个对象 怎么能 | 更新日期: 2023-09-27 18:06:31

我已经为WinCC (Siemens) (SCADA)编写了一个用户控件。现在我想传递一个指向控件的指针。要做到这一点,唯一的方法是:将指针写入属性。

WinCC只有这些方法来设置属性

  • SetPropBOOL
  • SetPropChar
  • SetPropDouble
  • SetPropWord

from control的属性以UInt作为数据类型,并且使用SetPropDouble方法从对象中设置地址。

WinCC全局脚本

//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 );

我已经调试了我的控制(钩子WinCC-process),我看到属性集被分配了一个地址值,例如0x03041080。

现在的问题:我怎么能得到对象在c# (.Net)上的地址?

My try抛出一个异常: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:我已经改变了我的代码使用STRING

WinCC

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

c#现在是

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

其它发现!

来自ado对象的地址不在调用我的控件的进程内存中(使用ollydbg进行调试)。WinCC有两个程序:PDLRT.exe用于可视化(这是调用我的控件)和SCRIPT.exe用于运行GLOBAL-SCRIPT (Ansi-C)。

从PDLRT,我可以从ADO-Object访问指针地址。通过在c#中调用ADO-object-address的GCHandle,抛出异常。( ExecutionEngineException )

我怎么能得到一个对象从指针地址

我不知道c#是否可以通过指针访问像这样的c++。

无论如何,this: (DWORD)(&autoDB)是错误的,它将指针的地址作为属性的值,这是毫无意义的。

需要指针的值,即(DWORD) autoDB

同样,SetPropDouble()接受double类型的值,即浮点数。这将不是一个很好的方式来共享指针,这是一个(大)整数。尝试一些不同的表示,字符串可能工作,如果你不能访问一个足够大的整数

Ok,

很久以前,我已经请求Siemens的支持。

Siemens:加载的dll、控件等加载在单独的内存中,而不是在应用程序(主)内存中。内存地址- dll之间的共享,控制....不起作用。它们都有一个独立的内存

超级。唯一的方法:管道或其他通信实现(TCP/IP,…)。