【问题标题】:How can i get an object from pointer-address如何从指针地址获取对象
【发布时间】:2014-06-04 09:37:38
【问题描述】:

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

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

  • SetPropBOOL
  • SetPropChar
  • SetPropDouble
  • SetPropWord

控件的属性具有 UInt 作为数据类型,我使用 SetPropDouble 方法设置对象的地址。

WinCC 全局脚本 (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 );

我已经调试了我的控件(挂钩 WinCC 进程),我看到属性集被分配了一个地址值,例如0x03041080.

现在的问题是:如何在 c# (.Net) 中获取对象的地址?

我的尝试抛出异常: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;
        }
    }
}

好的:我已将代码更改为使用 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-Object 的地址不在调用我的控件的进程内存中(使用 ollydbg 进行调试)。 WinCC 有两个程序:用于可视化的 PDLRT.exe(这是调用我的控件)和用于运行 GLOBAL-SCRIPT (Ansi-C) 的 SCRIPT.exe。

从 PDLRT,我可以访问来自 ADO-Object 的指针地址。通过在 ADO-object-address 的 C# 中调用 GCHandle,将引发异常。 (ExecutionEngineException)

【问题讨论】:

    标签: c# c scada


    【解决方案1】:

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

    不管怎样,这个:(DWORD)(&autoDB)是错误的,将指针的地址作为属性的值,这是没有意义的。

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

    另外,SetPropDouble() 接受 double 类型的值,即浮点数。这不是共享指针的好方法,指针是(大)整数。尝试一些不同的表示,如果您无法访问足够大的整数,字符串可能会起作用。

    【讨论】:

    • opps sry,这是另一种尝试:正确的代码没有,我已经改变了这个错误
    【解决方案2】:

    好的,

    很久以前,我已经向Siemens寻求支持。

    Siemens:加载的 Dll、控件等加载在单独的内存中,而不是在应用程序(主)内存中。 Dlls,控件之间的内存地址共享....不起作用。都有独立的记忆。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 2018-10-19
      • 1970-01-01
      相关资源
      最近更新 更多