RE: [Boost-Users] Re: boost::intrusive_ptr and Managed C++?

Hello Drew,
I implement managed assembly in mc++. I use c++ library with smart pointers
and stlport on the interface to implement a functionality in unmanaged c++,
even if it is exposed to .net through managed classes. So this scenario in
general works.
Holger has already answered you, I see also the problem in different
heaps/runtime versions. You must ensure the same versions of the runtime
(not only debug/release but also version of msvs - 6, 7, 7.1) and of the
templated libraries used (in my case stlport for 6, 7, 7.1, which also must
use the same runtime). I use msvcrt/msvcrtd everywhere and link everything
automatically using pragmas to prevent strange errors from manual
configuration. It can look complex but in reality it is pretty simple.
The second option (as Holger says) is to make a simple facade to the c++
library (all you might use), which will not have templates (here smart
pointers) on the interface, and to use this facade instead.
Good Luck,
Ferda
P.S. with the first option you will come to problems if you register the
assembly for CCW but that's another story...
-----Original Message-----
From: Holger Grund [mailto:yg-boost-users@gmane.org]
Sent: Wednesday, August 20, 2003 18:18
To: boost-users@yahoogroups.com
Subject: [Boost-Users] Re: boost::intrusive_ptr and Managed C++?
"Drew"
I originally posted this to microsoft.public.dotnet.languages.vc, but they referred me back to here.
Has anyone used boost's intrusive_ptr with Managed C++ extensions?
Mmh, not really. And it actually doesn't (currently ?) sound like a very compelling idea to me.
I have a small project where the executable (managed) is linked to a native C++ dll.
The code looks like:
int _tmain() { boost::intrusive_ptr<Unmanaged> pUn = __nogc new Unmanaged();
return 0; }
when I exit out of main, boost::intrusive_ptr_release() throws an exception. The last known method called is:
UnmanagedLib.dll!_CrtIsValidHeapPointer(...) Line 1807
This probably is not related to the managed extensions. It's more likely that intrusive_ptr's dtor calls into the DLL to free the pointer which is only possible if both modules use the DLL version of the CRT. The message indicates that the pointer to be freed is bogus or more likely from another heap. This is caused by a mismatch of the CRTs used by the main program and the DLL. You could use the /MD[d] option for both projects, so that both modules share a common CRT heap. I'd prefer to move intrusive_ptr_add_ref/release functions to the program that uses the instrusive_ptr. Don't export these functions from the DLL. Rather include these functions at build time. That way you ensure, that operator delete is called from the same module as operator new and everything should be fine.
Unmanaged* pUm = new Unmanaged(); delete pUm;
Yep. Same module. No problem. hth -hg ------------------------ Yahoo! Groups Sponsor ---------------------~--> Buy Ink Cartridges or Refill Kits for Your HP, Epson, Canon or Lexmark Printer at Myinks.com. Free s/h on orders $50 or more to the US & Canada. http://www.c1tracking.com/l.asp?cid=5511 http://us.click.yahoo.com/l.m7sD/LIdGAA/qnsNAA/EbFolB/TM ---------------------------------------------------------------------~-> Info: http://www.boost.org Wiki: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl Unsubscribe: mailto:boost-users-unsubscribe@yahoogroups.com Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/

"Ferdinand Prantl"
The second option (as Holger says) is to make a simple facade to the c++ library (all you might use), which will not have templates (here smart pointers) on the interface, and to use this facade instead.
Did I say that? Anyway, I absolutely agree. I just want to point out that IMHO the best solution is to _not_ export instrusive_ptr_add_ref and _release. If you do new and delete are called from different modules which works only if the same CRT instance is used. And that works only if both link against the exact same version of the CRT dll (that is both linking against a static CRT still yields to instances => two heaps => error). While we're at it, it's almost always a bad thing to export classes or functions that rely on classes from a DLL. DLLs are a run time concept. They don't have any clue which version of the compiler a consumer is built with. E.g. say you export a function void foo( std::string& s ) { s = "Hello World!"; } The DLL is built with the version A of the compiler and STL and the consuming application is built with version B. There is no guarantee for a binary compatibility between the two version. And indeed the code above will break if version 6 & 7 of VC are used (The former used a COW scheme while the second uses a short string optimization). Also, do note that the DLL CRT now supports side by side sharing. While I am in rant mode the catch(...) thing is also a very bad idea in VC. This currently catches (this will be fixed in 8.0) structured exception that are not C++ exception. That way serious error conditions are silently ignored. -hg

"Holger Grund"
While I am in rant mode the catch(...) thing is also a very bad idea in VC. This currently catches (this will be fixed in 8.0) structured exception that are not C++ exception. That way serious error conditions are silently ignored.
See http://www.boost.org/more/error_handling.html for a workaround. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams"
While I am in rant mode the catch(...) thing is also a very bad
idea
in VC. This currently catches (this will be fixed in 8.0) structured exception that are not C++ exception. That way serious error conditions are silently ignored.
See http://www.boost.org/more/error_handling.html for a workaround.
Thanks David, I've discussed this issue several times with the MS guys. But noone came up with that workaround. From my first tests this works just fine. Thanks! -hg
participants (3)
-
David Abrahams
-
Ferdinand Prantl
-
Holger Grund