locked
reinterpret_cast and reference-counted classes

    Question

  • In our SQLite3 component, we pass our database object into a C function using 

    sqlite3_update_hook(sqlite, UpdateHook, reinterpret_cast<void*>(this));

    When the UpdateHook callback is invoked, one of the parameters is reinterpret_casted back to the reference counted class

    Database^ database = reinterpret_cast<Database^>(data);

    database->OnChange(action,dbName,tableName,rowId);

    Now we are wondering how the reference counting in this scenario works behind the scenes. The disassembly shows a call to __abi_winrt_ptr_ctor and then __abi_winrt_ptr_dtor afterwards, suggesting that the reference count will first be increased when doing the reinterpret_cast an then decreased when leaving the scope. Could someone shed some light on that?

    Edit: In case you're interested, you can find the whole code here: https://github.com/doo/SQLite3-WinRT/blob/master/SQLite3/Database.cpp
    Thursday, July 12, 2012 10:42 AM

Answers

  • You're creating a new object handle ptr that points to the old object handle, so the ref count of the original object needs to be incremented. Once the new ptr goes out of scope, it's destroyed and the ref count needs to be decremented.

    You can find the source for _abi_winrt_ptr_ctor in 'c:\Program Files\Microsoft Visual Studio 11.0\VC\include\vccorlib.h'. Under the covers, it's converts the Platform::Object^ to an __abi_IUnknown ptr and then calls add ref on the pUnknown when you construct the new Database^ from the pointer to the origianl database object reference.

    • Marked as answer by Marcus Ilgner Friday, July 13, 2012 6:08 AM
    Thursday, July 12, 2012 9:48 PM
    Moderator

All replies

  • You're creating a new object handle ptr that points to the old object handle, so the ref count of the original object needs to be incremented. Once the new ptr goes out of scope, it's destroyed and the ref count needs to be decremented.

    You can find the source for _abi_winrt_ptr_ctor in 'c:\Program Files\Microsoft Visual Studio 11.0\VC\include\vccorlib.h'. Under the covers, it's converts the Platform::Object^ to an __abi_IUnknown ptr and then calls add ref on the pUnknown when you construct the new Database^ from the pointer to the origianl database object reference.

    • Marked as answer by Marcus Ilgner Friday, July 13, 2012 6:08 AM
    Thursday, July 12, 2012 9:48 PM
    Moderator
  • [adding to what Steve Home posted]

    Marcus,

    You may also notice that in some scenarios when you do a similar cast, the AddRef/Release is optimized away in release-mode. So I wouldn't worry too much about the ref-counting from a performance perspective (assuming that was your original concern).


    http://blog.voidnish.com

    Friday, July 13, 2012 1:16 PM
  • I was merely curios when and if the reinterpret_cast would issue an AddRef in the first place because I was pretty certain that a Release would occur in any case when the object leaves the scope. It would have been bad if using reinterpret_cast this way did confuse the reference count.
    Friday, July 13, 2012 1:29 PM