что за volatile?!
Ситуация следующая. Пробую написать свой COM-объект. Вычитал, что при подсчете ссылок на объект для нормальной работы с потоками надо использовать WinApi функции IncterlockedIncrement() и InterlockedDecrement(). Они-то и не хотят работать. Автор книги компилировал свои программы в MS VS 5.0, и, как я полагаю, они прекрасно работали. Я использую MS VS .NET 7.1. Думаю, что из-за разницы в компиляторах и возникает эта проблема. Исходный код приблизительно такой:
[FONT=courier new]
class Component : public IUnknown ...
{
public:
...
... AddRef();
... Release();
...
private:
long m_cRef;
...
};
...
... Component::AddRef()
{
return InterlockedIncrement( &m_cRef );
}
... Component::Release()
{
... InterlockedDecrement( &m_cRef );
...
}
[/FONT]
При вызовах этих функций компилятор выдает ошибку, мол не могу прочитать память по такому-то адресу. А если заменить их на ++m_cRef и --m_cRef, то все работает нормально. В MSDN эти функции объявлены так:
[FONT=courier new]
LONG InterlockedDecrement( LONG volatile* Addend );
LONG InterlockedIncrement( LONG volatile* Addend );
[/FONT]
Не знаю точно, но, наверное, в 5-ой версии студии этих volatile не было. Что это такое и зачем нужно? Или проблема вовсе не в этом? Может, кто-нибудь объяснить? Буду очень благодарен.
P.S. Оська Windows 2003 Server
Цитата:
Originally posted by Романтик
Всем привет.
Ситуация следующая. Пробую написать свой COM-объект. Вычитал, что при подсчете ссылок на объект для нормальной работы с потоками надо использовать WinApi функции IncterlockedIncrement() и InterlockedDecrement(). Они-то и не хотят работать. Автор книги компилировал свои программы в MS VS 5.0, и, как я полагаю, они прекрасно работали. Я использую MS VS .NET 7.1. Думаю, что из-за разницы в компиляторах и возникает эта проблема. Исходный код приблизительно такой:
[FONT=courier new]
class Component : public IUnknown ...
{
public:
...
... AddRef();
... Release();
...
private:
long m_cRef;
...
};
...
... Component::AddRef()
{
return InterlockedIncrement( &m_cRef );
}
... Component::Release()
{
... InterlockedDecrement( &m_cRef );
...
}
[/FONT]
При вызовах этих функций компилятор выдает ошибку, мол не могу прочитать память по такому-то адресу. А если заменить их на ++m_cRef и --m_cRef, то все работает нормально. В MSDN эти функции объявлены так:
[FONT=courier new]
LONG InterlockedDecrement( LONG volatile* Addend );
LONG InterlockedIncrement( LONG volatile* Addend );
[/FONT]
Не знаю точно, но, наверное, в 5-ой версии студии этих volatile не было. Что это такое и зачем нужно? Или проблема вовсе не в этом? Может, кто-нибудь объяснить? Буду очень благодарен.
P.S. Оська Windows 2003 Server
Всем привет.
Ситуация следующая. Пробую написать свой COM-объект. Вычитал, что при подсчете ссылок на объект для нормальной работы с потоками надо использовать WinApi функции IncterlockedIncrement() и InterlockedDecrement(). Они-то и не хотят работать. Автор книги компилировал свои программы в MS VS 5.0, и, как я полагаю, они прекрасно работали. Я использую MS VS .NET 7.1. Думаю, что из-за разницы в компиляторах и возникает эта проблема. Исходный код приблизительно такой:
[FONT=courier new]
class Component : public IUnknown ...
{
public:
...
... AddRef();
... Release();
...
private:
long m_cRef;
...
};
...
... Component::AddRef()
{
return InterlockedIncrement( &m_cRef );
}
... Component::Release()
{
... InterlockedDecrement( &m_cRef );
...
}
[/FONT]
При вызовах этих функций компилятор выдает ошибку, мол не могу прочитать память по такому-то адресу. А если заменить их на ++m_cRef и --m_cRef, то все работает нормально. В MSDN эти функции объявлены так:
[FONT=courier new]
LONG InterlockedDecrement( LONG volatile* Addend );
LONG InterlockedIncrement( LONG volatile* Addend );
[/FONT]
Не знаю точно, но, наверное, в 5-ой версии студии этих volatile не было. Что это такое и зачем нужно? Или проблема вовсе не в этом? Может, кто-нибудь объяснить? Буду очень благодарен.
P.S. Оська Windows 2003 Server
Спецификатор [color=#3366FF]volatile[/color] - это подсказка компилятору, что объект может изменять свое значение не описанным в языке образом, так что агрессивной оптимизации следует избегать.(из Страуструпа)
И как ты думаешь, почему сиё не хочет компилиться?
Цитата:
Originally posted by Романтик
И как ты думаешь, почему сиё не хочет компилиться?
И как ты думаешь, почему сиё не хочет компилиться?
Все должно еомпилится правильно,мо у тебя проблема не в этом? Покажи кода побольше,и как ты создаеш эти объекты.
Цитата:
Originally posted by Романтик
И как ты думаешь, почему сиё не хочет компилиться?
И как ты думаешь, почему сиё не хочет компилиться?
попробуй так
Код:
LONG InterlockedIncrement(volatile LONG * Addend );
Цитата:
Originally posted by solovey
попробуй так
хотя проблема скорее всего в чем-то другом
попробуй так
Код:
LONG InterlockedIncrement(volatile LONG * Addend );
короче говоря, если переменную пометить этим спецификатором, другая программа сможет свободно ее изменять
мда... ошибка как всегда была рядом. Оказывается в Release() сначала удалял объект, а потом возвращал его переменную =)