Как я могу получить объект по адресу указателя

StackOverflow https://stackoverflow.com//questions/24033938

  •  21-12-2019
  •  | 
  •  

Вопрос

я написал пользовательский элемент управления для 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.

Теперь вопрос:Как я могу получить объект в С# (.Net) по адресу?

Моя попытка выдает исключение: ИсполнениеEngineException

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

И С# сейчас

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.При вызове GCHandle в C# адреса объекта ADO выдается исключение.(ИсполнениеEngineException)

Это было полезно?

Решение 2

ОК,

Давным-давно, и я задаю поддержку от Siemens.

Siemens: загруженные DLL, элементы управления и так далее находятся в разделенной памяти, а не в памяти приложения (главная).Адрес памяти - доля между dlls, элементы управления .... не работает.У всех есть разделенная память.

Супер.Только способ: трубы или другие реализации связи (TCP / IP, ...).

Другие советы

Я понятия не имею, может ли C# получить доступ через указатель на C++ таким образом.

Несмотря ни на что, это: (DWORD)(&autoDB) неверно, это ставит адрес указателя как стоимость собственности, что бессмысленно.

Вам нужно значение указателя, т.е. (DWORD) autoDB.

Также, SetPropDouble() принимает значение типа double, т.е.число с плавающей запятой.Это будет не очень хороший способ поделиться указателем, который представляет собой (большое) целое число.Попробуйте другое представление. Строка может работать, если у вас нет доступа к достаточно большому целому числу.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top