I am getting an error when I try to run the following code when I set the
variable to NULL?

#import "..\Orchestra\Orchestra\Debug\Orchestra.dll"

using namespace OrchestraLib;

DWORD WINAPI ThreadFunction(LPVOID lpvParameter);

int _tmain(int argc, _TCHAR* argv[])

{

::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);

IClarinetPtr spIClarinet;

spIClarinet.CreateInstance(__uuidof(Clarinet));

spIClarinet->Sound(1000, 1000);

spIClarinet->Release();

spIClarinet = NULL;

The error happens in comip.h at the point below:

template<> _com_ptr_t& operator=(Interface* pInterface) throw()

{

if (m_pInterface != pInterface) {

Interface* pOldInterface = m_pInterface;

m_pInterface = pInterface;

_AddRef();

if (pOldInterface != NULL) {

pOldInterface->Release();
<---------------------------------------------------||||||||||||

}

}

return *this;

}

The error happens when I debug the code. It's a runtime error. Here's the
message it gives me:

Unhandled exception at 0x00412076 in Test.exe: 0xC0000005: Access violation
reading location 0xfeeefef6.

If anyone could tell me anything, I would really appreciate it. The .dll
file is one that I created with ATL 8. I use VS2008.

Daniel

Re: runtime error when setting pointer to interface to NULL by Alf

Alf
Sat Jul 26 00:37:59 CDT 2008

* Daniel:
> I am getting an error when I try to run the following code when I set the
> variable to NULL?
>
> #import "..\Orchestra\Orchestra\Debug\Orchestra.dll"
>
> using namespace OrchestraLib;
>
> DWORD WINAPI ThreadFunction(LPVOID lpvParameter);
>
> int _tmain(int argc, _TCHAR* argv[])

Just in passing, using the Microsoft's braindead "T" functionality is an almost
sure way to screw up. Have you tried compiling your code as both Unicode and
ANSI? My guess is that one of those will not compile, and then "T" is just
misleading and a source of complexity and trouble; don't use it.


> {
>
> ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
>
> IClarinetPtr spIClarinet;
>
> spIClarinet.CreateInstance(__uuidof(Clarinet));
>
> spIClarinet->Sound(1000, 1000);
>
> spIClarinet->Release();

You're messing up the reference count.

The smart pointer has no idea and no way to know that you're calling Release on
the referenced object.


> spIClarinet = NULL;
>
> The error happens in comip.h at the point below:

Not surprising, but be happy that it's detected in some way.

This code is invoking Undefined Behavior where there's no guarantee that such
things will be detected.


Cheers, & hth.,

- Alf


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Re: runtime error when setting pointer to interface to NULL by Daniel

Daniel
Sat Jul 26 01:49:48 CDT 2008

If the problem is that I messed up the reference count, then what is the
solution?

Daniel

"Alf P. Steinbach" <alfps@start.no> wrote in message
news:z62dnbbFZZWlJRfVnZ2dnUVZ_o3inZ2d@posted.comnet...
>* Daniel:
>> I am getting an error when I try to run the following code when I set the
>> variable to NULL?
>>
>> #import "..\Orchestra\Orchestra\Debug\Orchestra.dll"
>>
>> using namespace OrchestraLib;
>>
>> DWORD WINAPI ThreadFunction(LPVOID lpvParameter);
>>
>> int _tmain(int argc, _TCHAR* argv[])
>
> Just in passing, using the Microsoft's braindead "T" functionality is an
> almost sure way to screw up. Have you tried compiling your code as both
> Unicode and ANSI? My guess is that one of those will not compile, and then
> "T" is just misleading and a source of complexity and trouble; don't use
> it.
>
>
>> {
>>
>> ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
>>
>> IClarinetPtr spIClarinet;
>>
>> spIClarinet.CreateInstance(__uuidof(Clarinet));
>>
>> spIClarinet->Sound(1000, 1000);
>>
>> spIClarinet->Release();
>
> You're messing up the reference count.
>
> The smart pointer has no idea and no way to know that you're calling
> Release on the referenced object.
>
>
>> spIClarinet = NULL;
>>
>> The error happens in comip.h at the point below:
>
> Not surprising, but be happy that it's detected in some way.
>
> This code is invoking Undefined Behavior where there's no guarantee that
> such things will be detected.
>
>
> Cheers, & hth.,
>
> - Alf
>
>
> --
> A: Because it messes up the order in which people normally read text.
> Q: Why is it such a bad thing?
> A: Top-posting.
> Q: What is the most annoying thing on usenet and in e-mail?



Re: runtime error when setting pointer to interface to NULL by Daniel

Daniel
Sat Jul 26 02:03:00 CDT 2008

I just rebuilt the solution that created Orchestra.dll. There were no
errors. How do I determine whether it was compiled in Unicode or ANSI?

Daniel

"Alf P. Steinbach" <alfps@start.no> wrote in message
news:z62dnbbFZZWlJRfVnZ2dnUVZ_o3inZ2d@posted.comnet...
>* Daniel:
>> I am getting an error when I try to run the following code when I set the
>> variable to NULL?
>>
>> #import "..\Orchestra\Orchestra\Debug\Orchestra.dll"
>>
>> using namespace OrchestraLib;
>>
>> DWORD WINAPI ThreadFunction(LPVOID lpvParameter);
>>
>> int _tmain(int argc, _TCHAR* argv[])
>
> Just in passing, using the Microsoft's braindead "T" functionality is an
> almost sure way to screw up. Have you tried compiling your code as both
> Unicode and ANSI? My guess is that one of those will not compile, and then
> "T" is just misleading and a source of complexity and trouble; don't use
> it.
>
>
>> {
>>
>> ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
>>
>> IClarinetPtr spIClarinet;
>>
>> spIClarinet.CreateInstance(__uuidof(Clarinet));
>>
>> spIClarinet->Sound(1000, 1000);
>>
>> spIClarinet->Release();
>
> You're messing up the reference count.
>
> The smart pointer has no idea and no way to know that you're calling
> Release on the referenced object.
>
>
>> spIClarinet = NULL;
>>
>> The error happens in comip.h at the point below:
>
> Not surprising, but be happy that it's detected in some way.
>
> This code is invoking Undefined Behavior where there's no guarantee that
> such things will be detected.
>
>
> Cheers, & hth.,
>
> - Alf
>
>
> --
> A: Because it messes up the order in which people normally read text.
> Q: Why is it such a bad thing?
> A: Top-posting.
> Q: What is the most annoying thing on usenet and in e-mail?



Re: runtime error when setting pointer to interface to NULL by Daniel

Daniel
Sat Jul 26 02:06:41 CDT 2008

When you said not to use the braindead "T" functionality, do you mean the
_TCHAR* notation? Should I just use int main() instead? Is that what you
mean?

Daniel
"Alf P. Steinbach" <alfps@start.no> wrote in message
news:z62dnbbFZZWlJRfVnZ2dnUVZ_o3inZ2d@posted.comnet...
>* Daniel:
>> I am getting an error when I try to run the following code when I set the
>> variable to NULL?
>>
>> #import "..\Orchestra\Orchestra\Debug\Orchestra.dll"
>>
>> using namespace OrchestraLib;
>>
>> DWORD WINAPI ThreadFunction(LPVOID lpvParameter);
>>
>> int _tmain(int argc, _TCHAR* argv[])
>
> Just in passing, using the Microsoft's braindead "T" functionality is an
> almost sure way to screw up. Have you tried compiling your code as both
> Unicode and ANSI? My guess is that one of those will not compile, and then
> "T" is just misleading and a source of complexity and trouble; don't use
> it.
>
>
>> {
>>
>> ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
>>
>> IClarinetPtr spIClarinet;
>>
>> spIClarinet.CreateInstance(__uuidof(Clarinet));
>>
>> spIClarinet->Sound(1000, 1000);
>>
>> spIClarinet->Release();
>
> You're messing up the reference count.
>
> The smart pointer has no idea and no way to know that you're calling
> Release on the referenced object.
>
>
>> spIClarinet = NULL;
>>
>> The error happens in comip.h at the point below:
>
> Not surprising, but be happy that it's detected in some way.
>
> This code is invoking Undefined Behavior where there's no guarantee that
> such things will be detected.
>
>
> Cheers, & hth.,
>
> - Alf
>
>
> --
> A: Because it messes up the order in which people normally read text.
> Q: Why is it such a bad thing?
> A: Top-posting.
> Q: What is the most annoying thing on usenet and in e-mail?



Re: runtime error when setting pointer to interface to NULL by Alex

Alex
Sat Jul 26 02:31:57 CDT 2008

"Daniel" wrote:
> If the problem is that I messed up the reference count, then
> what is the solution?

The solition is to stop worrying about reference count. This is
responsibiliy of smart pointer. Thet's why they call it smart,
after all. You should not call `QueryInterface', `AddRef', and
`Release' methods on smart pointer. It all happens automatically.
If you don't need the pointer anymore, then just set it to NULL.
Or don't do anything, smart pointer will call `Release' in its
destructor when goes out of scope.

I suggest you to learn a bit about compiler COM support:

"Compiler COM Support"
http://msdn.microsoft.com/en-us/library/h31ekh7e.aspx

Particularly, read about `_com_ptr_t' class.

Alex



Re: runtime error when setting pointer to interface to NULL by Alex

Alex
Sat Jul 26 02:34:17 CDT 2008

"Daniel" wrote:
> How do I determine whether it was compiled in Unicode or ANSI?

Go to properties of the project, then in "General" category pay
attention to the "Character Set" property.


Alex



Re: runtime error when setting pointer to interface to NULL by Alex

Alex
Sat Jul 26 02:40:48 CDT 2008

"Daniel" wrote:
> When you said not to use the braindead "T" functionality, do you
> mean the _TCHAR* notation? Should I just use int main()
> instead? Is that what you mean?

Alf tries to say that the "T" functionality is quite obsolete
nowadays. It was useful in the past, when the same code could be
built both as ANSI and Unicode. However, now Win9x line of OS is
almost extinct. So, there is no compelling reason to maintain ANSI
builds anymore. Read here about text mapping:

"Generic-Text Mappings in Tchar.h"
http://msdn.microsoft.com/en-us/library/c426s321.aspx

Alex



Re: runtime error when setting pointer to interface to NULL by Alf

Alf
Sat Jul 26 02:53:31 CDT 2008

* Daniel:
> If the problem is that I messed up the reference count, then what is the
> solution?

Don't mess it up.

That's not facetious. In order to do any useful software development you /have/
to engage your brain. If one could make software by following simple mechanical
rules then, ... oh, sorry, yes, that's how it actually is today. But the point
is, you can do much better! And actually anyone can, just by starting to think.

So, think about it: the current code messes up the reference count. Exactly how
does it manage to do that? Could there be a hint in the placement of my comment?


Cheers, & hth. in a longer view,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Re: runtime error when setting pointer to interface to NULL by Daniel

Daniel
Sat Jul 26 08:18:32 CDT 2008

Why does Microsoft put that code in by default when a programmer creates a
Win32 Console Application Project?

Daniel

"Alex Blekhman" <tkfx.REMOVE@yahoo.com> wrote in message
news:%23MmraLv7IHA.2224@TK2MSFTNGP05.phx.gbl...
> "Daniel" wrote:
>> When you said not to use the braindead "T" functionality, do you mean the
>> _TCHAR* notation? Should I just use int main() instead? Is that what
>> you mean?
>
> Alf tries to say that the "T" functionality is quite obsolete nowadays. It
> was useful in the past, when the same code could be built both as ANSI and
> Unicode. However, now Win9x line of OS is almost extinct. So, there is no
> compelling reason to maintain ANSI builds anymore. Read here about text
> mapping:
>
> "Generic-Text Mappings in Tchar.h"
> http://msdn.microsoft.com/en-us/library/c426s321.aspx
>
> Alex
>



Re: runtime error when setting pointer to interface to NULL by Alex

Alex
Sat Jul 26 08:42:35 CDT 2008

"Daniel" wrote:
> Why does Microsoft put that code in by default when a programmer
> creates a Win32 Console Application Project?

If I were MS I could answer you. :) Probably it is there for
backward compatibility with existing code, I don't know for sure.
I think it should go. However, I am afraid that we're stuck with
this forever. Exactly as we're stuck with all these 16-bit
remnants like DWORD's and LP pointers in PSDK headers.

Alex



Re: runtime error when setting pointer to interface to NULL by David

David
Sat Jul 26 08:44:37 CDT 2008

Daniel wrote:
> Why does Microsoft put that code in by default when a programmer creates a
> Win32 Console Application Project?

Daniel:

Because it is still possible to compile and run "ANSI" applications, even though
Win9x is no longer supported by VC9.

There is nothing wrong with using the "T" functionality (despite what Alf says),
though if you use it you should use it consistently. One way to check consistent
usage is to compile in both ANSI and Unicode mode.

However, all new projects should use Unicode build, because UTF-16 is the native
character set of all the OS's that VC9 applications will run on. So if you
prefer, you can just use wchar_t and L"" strings everywhere (this is what Alf
would suggest).

--
David Wilkinson
Visual C++ MVP

Re: runtime error when setting pointer to interface to NULL by Igor

Igor
Sat Jul 26 10:12:26 CDT 2008

"Daniel" <newsonly@cableone.net> wrote in message
news:eV$rzht7IHA.5596@TK2MSFTNGP02.phx.gbl
> spIClarinet->Release();
>
> spIClarinet = NULL;

Drop the first line, just do the second. Assigning NULL to a smart
pointer makes it release any pointer it held previously. Alternatively,
call

spIClarinet.Release();

Note .Release, not ->Release. It does the same as assigning NULL, but
perhaps in a more explicit and readable way.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: runtime error when setting pointer to interface to NULL by Daniel

Daniel
Sat Jul 26 22:46:54 CDT 2008


> call
>
> spIClarinet.Release();
>
> Note .Release, not ->Release. It does the same as assigning NULL, but
> perhaps in a more explicit and readable way.

thanks. That's one I need.



Re: runtime error when setting pointer to interface to NULL by Tim

Tim
Tue Jul 29 02:01:42 CDT 2008

"Daniel" <newsonly@cableone.net> wrote:
>
>I am getting an error when I try to run the following code when I set the
>variable to NULL?
>
>#import "..\Orchestra\Orchestra\Debug\Orchestra.dll"
>
>using namespace OrchestraLib;
>
>DWORD WINAPI ThreadFunction(LPVOID lpvParameter);
>
>int _tmain(int argc, _TCHAR* argv[])
>{
>::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
>IClarinetPtr spIClarinet;
>spIClarinet.CreateInstance(__uuidof(Clarinet));
>spIClarinet->Sound(1000, 1000);
>spIClarinet->Release();
>spIClarinet = NULL;

I assume from this code that IClarinetPtr is actually a typedef for
typedef CComPtr<IClarinet> IClarinetPtr;

Assuming that, those last two lines should be EITHER
spIClarinet.Release(); // notice . not ->
or
spIClarinet = 0;
Both do the same thing.

By calling spIClarinet->Release();, you are bypassing the smart pointer, so
it doesn't realize the release happened.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Re: runtime error when setting pointer to interface to NULL by Tim

Tim
Tue Jul 29 02:02:59 CDT 2008

"Igor Tandetnik" <itandetnik@mvps.org> wrote:
>"Daniel" <newsonly@cableone.net> wrote:
>
>> spIClarinet->Release();
>>
>> spIClarinet = NULL;
>
>Drop the first line, just do the second. Assigning NULL to a smart
>pointer makes it release any pointer it held previously. Alternatively,
>call
>
>spIClarinet.Release();
>
>Note .Release, not ->Release. It does the same as assigning NULL, but
>perhaps in a more explicit and readable way.

There's more to it than that. spIClarinet->Release() bypasses the smart
pointer code in CComPtr, so it doesn't realize the pointer was released. It
will just defer the crash until the destructor runs.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Re: runtime error when setting pointer to interface to NULL by Alex

Alex
Tue Jul 29 03:57:00 CDT 2008

"Tim Roberts" wrote:
>>#import "..\Orchestra\Orchestra\Debug\Orchestra.dll"
>> [...]
>
> I assume from this code that IClarinetPtr is actually a typedef
> for
> typedef CComPtr<IClarinet> IClarinetPtr;

Minor correction. Actually, it is a typedef for

typedef _com_ptr_t<IClarinet> IClarinetPtr

or to be more precise

_COM_SMARTPTR_TYPEDEF(IClarinet, __uuidof(IClarinet));


Alex



Re: runtime error when setting pointer to interface to NULL by Igor

Igor
Tue Jul 29 06:57:43 CDT 2008

"Tim Roberts" <timr@probo.com> wrote in message
news:63gt845681118djem5f1ukltla69miebs2@4ax.com
> "Igor Tandetnik" <itandetnik@mvps.org> wrote:
>>
>> spIClarinet.Release();
>>
>> Note .Release, not ->Release. It does the same as assigning NULL, but
>> perhaps in a more explicit and readable way.
>
> There's more to it than that. spIClarinet->Release() bypasses the
> smart pointer code in CComPtr

More to what than what? Was any part of "use .Release, not ->Release"
unclear?

Besides, the OP is asking about _com_ptr_t, not CComPtr. With CComPtr,
spIClarinet->Release() wouldn't even compile.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: runtime error when setting pointer to interface to NULL by Alf

Alf
Tue Jul 29 09:50:55 CDT 2008

* Igor Tandetnik:
> "Tim Roberts" <timr@probo.com> wrote in message
> news:63gt845681118djem5f1ukltla69miebs2@4ax.com
>> "Igor Tandetnik" <itandetnik@mvps.org> wrote:
>>> spIClarinet.Release();
>>>
>>> Note .Release, not ->Release. It does the same as assigning NULL, but
>>> perhaps in a more explicit and readable way.
>> There's more to it than that. spIClarinet->Release() bypasses the
>> smart pointer code in CComPtr
>
> More to what than what? Was any part of "use .Release, not ->Release"
> unclear?

I also reacted to the "there's more to it".


> Besides, the OP is asking about _com_ptr_t, not CComPtr. With CComPtr,
> spIClarinet->Release() wouldn't even compile.

Good samaritan that I am, for Tim, the technical: CComPtr::operator-> doesn't
return a pure T*, but returns the contained pointer downcasted to a
_NoAddRefReleaseOnCComPtr<T>*, which makes AddRef and Release private.

It's still possible to access AddRef and Release in other ways, but the
(compiler-specific) trick works in practice to catch such mistakes.


Cheers,

- Alf


PS: I think it's much better to just provide the technical info that one has
than to invite a back-and-forth exchange about it. Providing the technical info
=> everyone improves, scientific & engineering way. Making seemingly incorrect
statement based on special case knowledge => dominance games, political way
(although in this case it might have felt justified :-), I think, still ungood).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Re: runtime error when setting pointer to interface to NULL by Daniel

Daniel
Tue Jul 29 20:15:07 CDT 2008


> There's more to it than that. spIClarinet->Release() bypasses the smart
> pointer code in CComPtr, so it doesn't realize the pointer was released.
> It
> will just defer the crash until the destructor runs.


You're right. I did get that same error only at the end of execution.

Daniel



Re: runtime error when setting pointer to interface to NULL by Daniel

Daniel
Tue Jul 29 20:20:07 CDT 2008


> Besides, the OP is asking about _com_ptr_t, not CComPtr. With CComPtr,
> spIClarinet->Release() wouldn't even compile.

I didn't realize when I asked the question that I was actually asking about
a smart pointer. spIClarinet was declared by a type name created by ATL
when I created the Clarinet component object.

Daniel



Re: runtime error when setting pointer to interface to NULL by Daniel

Daniel
Tue Jul 29 20:21:33 CDT 2008


>> I assume from this code that IClarinetPtr is actually a typedef
>> for
>> typedef CComPtr<IClarinet> IClarinetPtr;
>
> Minor correction. Actually, it is a typedef for
>
> typedef _com_ptr_t<IClarinet> IClarinetPtr
>
> or to be more precise
>
> _COM_SMARTPTR_TYPEDEF(IClarinet, __uuidof(IClarinet));
>

What's the difference between the two typedef that you listed above?

Daniel



Re: runtime error when setting pointer to interface to NULL by Igor

Igor
Tue Jul 29 21:12:13 CDT 2008

"Daniel" <newsonly@cableone.net> wrote in message
news:eg6xoJe8IHA.2548@TK2MSFTNGP05.phx.gbl
>> Besides, the OP is asking about _com_ptr_t, not CComPtr. With
>> CComPtr, spIClarinet->Release() wouldn't even compile.
>
> I didn't realize when I asked the question that I was actually asking
> about a smart pointer. spIClarinet was declared by a type name
> created by ATL when I created the Clarinet component object.

Not by ATL - by #import directive. This is compiler built-in COM
support, unrelated to ATL.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: runtime error when setting pointer to interface to NULL by Igor

Igor
Tue Jul 29 21:13:50 CDT 2008

"Daniel" <newsonly@cableone.net> wrote in message
news:uU3GcKe8IHA.356@TK2MSFTNGP02.phx.gbl
>>> I assume from this code that IClarinetPtr is actually a typedef
>>> for
>>> typedef CComPtr<IClarinet> IClarinetPtr;
>>
>> Minor correction. Actually, it is a typedef for
>>
>> typedef _com_ptr_t<IClarinet> IClarinetPtr
>>
>> or to be more precise
>>
>> _COM_SMARTPTR_TYPEDEF(IClarinet, __uuidof(IClarinet));
>>
>
> What's the difference between the two typedef that you listed above?

None. The latter uses a macro that expands to (something very close to)
the former.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: runtime error when setting pointer to interface to NULL by Daniel

Daniel
Wed Jul 30 01:04:10 CDT 2008

> Not by ATL - by #import directive. This is compiler built-in COM support,
> unrelated to ATL.

Import a header? If so, how can I look at that header? Do you remember
which header it would be? Where would would I find that header?

Daniel



Re: runtime error when setting pointer to interface to NULL by Alex

Alex
Wed Jul 30 06:50:59 CDT 2008

"Daniel" wrote:
> Import a header? If so, how can I look at that header? Do you
> remember which header it would be? Where would would I find
> that header?

The #import directive creates .TLH/.TLI pair of files in the
output directory (usually Debug or Release).

Alex