«Нарушение прав доступа» с COleVariant - PullRequest
0 голосов
/ 22 февраля 2012

У меня есть функция

BOOL AltairListDialog::GetDocuments()
{
    CComQIPtr<AXAPILib::ICollection> m_Collection;
    HRESULT hr = m_Collection.CoCreateInstance(L"Axapi.Collection");
    AXAPILib::ICollection *indices = (AXAPILib::ICollection*) m_Collection.p;

    int status;
    COleVariant ind;
    ind.vt = VT_DISPATCH;
    ind.pdispVal = (IDispatch*) indices;

    return TRUE;
}

Я использую DLL, которая реализует AXAPILib :: ICollection.Функция возвращает «Нарушение прав доступа» после «return TRUE;»но я не знаю почему.Есть предложения?

1 Ответ

3 голосов
/ 22 февраля 2012

Что ж, поиск предложений не совсем подходит для формата вопросов и ответов Stack Overflow, поэтому было бы неправильно проголосовать за закрытие вопроса.С другой стороны, многие другие могут делать то же самое Bad Things ™, и им может быть полезно узнать об этом.Итак:

  1. Не используйте приведение в стиле C, например (AXAPILib::ICollection*) m_Collection.p.Если он не компилируется без приведения, то это просто неправильно .Добавление броска затем скрывает ошибку.

    В этом случае удаление конкретного броска не должно иметь никакого эффекта.Но совершенно нехорошо иметь такие приведения в коде.Они не только скрывают ошибки (подавляя предупреждения и ошибки), но и активно вносят ошибки.

  2. Не используйте приведение в стиле C, например (IDispatch*) indices.Если код не компилируется без приведения, то это просто неправильно .Добавление броска затем скрывает ошибку.

    Для этого второго броска удаление броска может иметь радикальный эффект или нет.Потенциальный радикальный эффект состоит в том, что код больше не компилируется.В этом случае вы знаете, что не так (хотя, скорее всего, здесь нет ничего плохого, кроме самого актерского состава).

  3. Не смешивайте умные указатели и «сырые» указатели, если вы действительно, действительноДЕЙСТВИТЕЛЬНО знаю, что вы делаете.

    Здесь деструктор умного указателя автоматически Release() получает объект по возвращении из функции.Объект создан вновь и не имеет других ссылок на него.Следовательно, его счетчик ссылок теперь обнуляется, и он уничтожается.

После возврата функции ссылка на уничтоженный объект является неопределенным поведением и, скорее всего, приведет к нежелательному поведению, которое у вас есть

One CURE FOR THAT * - попросить умный указатель передать свое владение содержащимся необработанным указателем.

Для конкретногоИнтеллектуальный указатель Microsoft, который вы используете в своей документации библиотеки MSDN, говорит, что вы можете сделать это, вызвав функцию Detach()Смущает, Wrt.именование, для умных указателей стандартной библиотеки C ++, и, как правило, это делается путем вызова члена release().Стоит отметить, что Microsoft Release() и стандартная библиотека release() - это две совершенно разные операции, соответственно уменьшение числа ссылок по сравнению с отсоединением ...

Наконец, неплохо бы не использовать Windows API BOOL, и вместо этого используйте C ++ bool.Одна из причин - просто избегать заглядывания в верхний регистр кода.Более техническая причина в том, что bool имеет только два допустимых значения, а именно false и true, в то время как BOOL имеет миллиард различных допустимых значений, которые, когда начинающий программист пишет такие вещи, как expression() == TRUE, вероятноприводит к ошибкам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...