23

First off, I should probably say that I'm probably at a grade 5 level with this stuff... I'm using a C++ add-in in a WPF application. Whenever I try to exit the program, I get this error:

Unhandled exception at 0x770d15de in Raptor.exe: 0xC0020001: The string binding is invalid.

I've been using this blog entry to try and figure the problem out, but I'm having no luck. One thing I noticed though, when I use the same C++ addin in a Console application, calling many of the same methods used in the WPF application, the Console exits without a problem.

I've also gone through the C++ code and cannot find a single static variable declared anywhere. There are static methods though.

Any help would be much appreciated!

EDIT: I enabled a number of debugging features to see where this breaks. It was breaking the sp_counted_impl.hpp file (Boost) on the last bracket of the following:

    virtual void dispose() // nothrow
    {
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
        boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
#endif
        boost::checked_delete( px_ );
    }
keynesiancross
  • 3,441
  • 15
  • 47
  • 87
  • Is the C++ code completely native (e.g., exposed via COM or P/Invoke), C++ with managed extensions (i.e., VS2003), or C++/CLI (VS2005 and later)? How is the C# code loading the C++ addin? It sounds like you have all the C++ source code and can make any necessary modifications (it's not a third-party component you're using); is that correct? – Bradley Grainger Aug 06 '12 at 21:10
  • Correct, but the code is 99% written by 3rd parties. I just kind of pushed buttons... It's in VS2008. I've complied using some \clr thing, it links a bunch of code (don't know what that does) and I did it as a MultiThreaded DLL. Once compiled, it exports a DLL, which I then add as a reference in my C# project – keynesiancross Aug 06 '12 at 21:13
  • OK, it sounds like the same issue I encountered (and blogged about); IIRC I could only reproduce it by using a `static` variable in a C++ method (not by using a global), so if you didn't find any `static` variables, I'm not sure what's causing it. You may need to enable unmanaged code debugging (project properties, Debug tab), enable Break when Thrown in Debug > Exceptions and see if debugging the exception in crtdll.c provides any clues... – Bradley Grainger Aug 06 '12 at 21:22
  • One other possibility: does this project have a `DllMain` function that does anything non-trivial? There is very little you can do inside `DllMain` without running into problems (see links here for examples/discussion: http://stackoverflow.com/q/5834508). If there's complicated uninitialisation code in your C++ DLL, that may be causing this problem. – Bradley Grainger Aug 06 '12 at 21:25
  • Thanks for the help - will give these a go. I don't know where DllMain is tbh. Unless it's hidden in the background somewhere... ha, just realized I referenced your blog. Thanks for putting that up there. One thing I noticed you said was this: Even though NativeMethod is emitted as native code, the disassembly showed that it registers a managed entry point for the NativeClass destructor (for staticNativeObject) with the atexit function. Is there a way I can do that to try and find atexit's, to try and nail down possible code that is causing it? – keynesiancross Aug 06 '12 at 21:54
  • Also - perhaps far less clean - but is there a way I can try-catch the way out of this and ignore it? Or a way for me to unload the dll manually first? Tbh, this is the kind of program that will be used by me and one other. As long as it works, and doesn't crash our computers, I'm not too bothered.... – keynesiancross Aug 06 '12 at 21:55
  • sorry, one last question. Would static variables in #include<...> cause the same thing? For example, I include #include and #include. Not sure if those have static's inside them... – keynesiancross Aug 06 '12 at 21:58
  • 1
    To find atexit's you could enable unmanaged code debugging and put a breakpoint in _onexit_nolock (C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\onexit.c in VS2008). Alternatively, put a breakpoint on line 444 of crtdll.c (same folder) and add a watch to `function_to_call`. Keep continuing the debug session until it throws an exception. The last `function_to_call` is probably the culprit; hopefully its name will provide a clue to search within the C++ code. – Bradley Grainger Aug 07 '12 at 02:33

1 Answers1

27

This occurs with certain DLLs that don't link with native libraries and thus their DllMain does not initialize some needed native subsystem (like CRT or ATL). Sounds like you have a mixed-mode DLL of some sort. One recommended solution is to remove the entry point from the managed DLL: Remove the Entry Point of the Managed DLL

  1. Link with /NOENTRY. In Solution Explorer, right-click the project node, click Properties. In the Property Pages dialog box, click Linker, click Command Line, and then add this switch to the Additional Options field.
  2. Link msvcrt.lib. In the Property Pages dialog box, click Linker, click Input., and then add msvcrt.lib to the Additional Dependencies property.
  3. Remove nochkclr.obj. On the Input page (same page as in the previous step), remove nochkclr.obj from the Additional Dependencies property.
  4. Link in the CRT. On the Input page (same page as in the previous step), add __DllMainCRTStartup@12 to the Force Symbol References property.

More detail can be found here: https://support.microsoft.com/en-us/kb/814472

Doc
  • 343
  • 3
  • 13
  • Thanks a lot - I'm trying that now. I did notice that nochkclr.obj was already not there... – keynesiancross Aug 08 '12 at 16:20
  • The link to Microsoft support doesn't work :(. Please update it! – Doc Jan 07 '15 at 12:29
  • 1
    Sadly, got a `LNK2001: unresolved external symbol __DllMainCRTStartup@12` – Patrizio Bertoni Nov 18 '16 at 10:33
  • @PatrizioBertoni: I had the same issue and found this [link]( https://social.msdn.microsoft.com/Forums/en-US/bf162181-864c-4c25-88b0-b56d1affe350/crtisvalidheappointer-vs-dllmaincrtstartup12-in-vs2008-x64?forum=netfx64bit). It basically says: _In 64-bit compiles, exported functions are not decorated. Use _DllMainCRTStartup (one underscore, no "@12" postfix)_ – Quirysse May 31 '18 at 15:10
  • Do you know how to do the Command line changes using cmake – anand_v.singh Sep 05 '22 at 03:32
  • One bazilion thanks. I'm fairly new to programming and I not only solved my issue, but learned an important concept today. – FranciscoNabas Jan 21 '23 at 19:51