Как установка одной переменной c # methodpoped влияет на другую? - PullRequest
7 голосов
/ 31 марта 2011

Этот действительно меня озадачил.Я работаю с другим разработчиком, который позвонил мне, потому что он не мог поверить в то, что видел.Мы пошли вместе с отладчиком, и я тоже это видел, и у меня не было никаких объяснений.Вот сценарий.Он пишет метод, который взаимодействует с сторонним COM-объектом через автоматически сгенерированную оболочку COM (генерируемую простым добавлением COM-компонента в качестве ссылки. Вот верх его метода:

  public bool RefolderDocument(ref IManDocument oDoc)
    {
        string strCustom1 = (string) oDoc.GetAttributeValueByID(imProfileAttributeID.imProfileCustom1);
        string strCustom2 = (string) oDoc.GetAttributeValueByID(imProfileAttributeID.imProfileCustom2);

Целькода состоит в том, чтобы получить номер проекта и номер подпроекта из объекта «документ» (oDoc).

Вот что происходит, когда вы проходите шаг. После первого присваивания strCustom1 имеет ожидаемое значение «32344» (aномер проекта), а strCustom2 пуст, как и ожидалось. После второго назначения strCustom2 получает номер подпроекта "0002" - , но strCustom1 был изменен на 32334 - один символ был изменен!?

Меня поразило какое-то старое переполнение стека на языке C (чего я не ожидал в управляемом приложении, даже если оно взаимодействовало с COM-компонентом). Мы все были сбиты с толку. В попыткевзломать эту причуду, я попытался скопировать содержимое первой строки в другое место, например:

  public bool RefolderDocument(ref IManDocument oDoc)
    {
        string strCustom1 = string.Copy((string)oDoc.GetAttributeValueByID(imProfileAttributeID.imProfileCustom1));
        string strCustom2 = string.Copy((string)oDoc.GetAttributeValueByID(imProfileAttributeID.imProfileCustom2));

Те же результаты!В этот момент мы ухватились за соломинку и сбросили код с .NET 4 до .NET 3.5 (CLR 2), но без изменений.Возможно, один важный момент заключается в том, что это услуга, и мы подключаемся к процессу обслуживания.Сборка нацелена на x86, а расположение службы определенно находится в папке сборки вывода отладки.

Есть ли логическое объяснение этому?Я озадачен тем, как действовать.

Ответы [ 4 ]

1 голос
/ 31 марта 2011

Я столкнулся с проблемами, похожими на те, которые вы описали.

В моем случае .NET / compiler / runtine / CLR работал отлично, и единственной проблемой было отображение отладчика в Visual Studio.неверные значения.Попробуйте записать свои значения, например, в System.Diagnostics.Trace или в консоль, чтобы проверить, так ли это.

1 голос
/ 31 марта 2011

Скорее всего, правила COM-памяти не соблюдаются COM-объектом, и он перезаписывает память, которой, по мнению CLR, он владеет. Простые вещи, такие как не создание нового объекта для GetEnumerator (), могут реально испортить взаимодействие COM и кеширование, которое оно делает.

Вы также должны понимать, что способ, которым на самом деле работает вызов COM, заключается в передаче ссылки на память для строки. Хотя вы называете это как:

str = oDoc.GetAttributeValueByID(imProfileAttributeID.imProfileCustom1)

Это действительно называется больше как:

hresult = oDoc.GetAttributeValueByID(imProfileAttributeID.imProfileCustom1,&str)

Таким образом, вы можете видеть, что COM-объект имеет указатель прямо в память CLR.

Другими словами, посмотрите на объект COM, а не на код .NET.

1 голос
/ 31 марта 2011

Похоже, что strCustom1 и strCustom2 были установлены как ссылки на результат GetAttributeValueByID. Я не знаю почему, и было бы интересно узнать, может ли кто-то еще здесь (пейджинг доктора Скита, лол ...).

В краткосрочной перспективе, я думаю, вы найдете, что это решит проблему для вас ...

 public bool RefolderDocument(ref IManDocument oDoc)
    {
        string strCustom1 = "" + string.Copy((string)oDoc.GetAttributeValueByID(imProfileAttributeID.imProfileCustom1));
        string strCustom2 = "" + string.Copy((string)oDoc.GetAttributeValueByID(imProfileAttributeID.imProfileCustom2));

Моя идея в основном состоит в том, чтобы он вычислял выражение, а не работал непосредственно со ссылкой ...

Martin.

Ps. Что со строкой. Копия ()?

0 голосов
/ 31 марта 2011

Я не знаю точно, почему или как это происходит, и я надеюсь, что кто-то придет с ответом. В качестве обходного пути я бы проанализировал возвращенную строку в int, а затем выполнил бы второй оператор. По крайней мере, это обойдет проблему потерянного значения.

int Custom1 = int.Parse((string)oDoc.GetAttributeValueByID(imProfileAttributeID.imProfileCustom1));
int Custom2 = int.Parse((string)oDoc.GetAttributeValueByID(imProfileAttributeID.imProfileCustom2));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...