Crash on static variable initialization with MSVC 2013 - visual-c++

Hi folks!
Recently I've upgraded my developing environment. Namely, I've moved from Qt 4.8.4 and MSVC 2010 to Qt 5.3.1 and MSVC 2013. The problem I've faced is that my application crashes on launch, and stack trace proves that the crash happens during the initialization of some static class fields.
See the following example:
// header file
class MyClass : QObject
Q_OBJECT
public:
...
private:
static const QString CLASS_NAME;
// *.cpp file
const QString MyClass::CLASS_NAME = MyClass::tr("FOO"); // crash when calling tr()
const QString MyClass::CLASS_NAME = QObject::tr("FOO"); // but this works normally
During debugging into Qt I've found that the MyClass::tr() method eventually calls QMetaObject::tr() and it appears that all the fields of the QMetaObject instance are NULL. The crash then occurs when referencing some of them.
Notable fact is that the crash is not reproduced on another machine with Ubuntu 14.04 and Qt 5.2.1.
Surely, I could just replace the MyClass name to the QObject one, but my project consists of 63 libraries so I'm afraid of possible translation conficts.

Well,
class QObject :
static QString tr ( const char * sourceText, const char * disambiguation = 0, int n = -1 )
tr is a static function, that means you cannot refer to the virtual methode table. (see C++ static virtual members?)
The problem is: you can overload the method, but the call to the base object is not called. Not sure how the macro Q_OBJECT is interfearing. But I think it will connect it later.
Did you verfiy if the resulting QString was translated using QObject::tr()?
Not quiet sure if this works. Need to test it.
Edit:
Checked it, indeed it only affect Qt 5.x, but please refer to http://qt-project.org/doc/qt-5/sourcebreaks.html
I remember they changed stuff in the translate api in Qt 5. Probably there could be the mess in some hidden code breaks.

Related

C++- Macro definition throwing error

I am new to c++ programming. I am trying few things
I tried using directive in following way as shown in below program just for trail it is throwing error
IDE used:VS 2015
language :VC++
Project type: library
Error occured is Error: Expected an identifier
This is in Stdafx.h
#define MANAGED_PUBLIC public ref
This is in trail.h
using namespace System;
namespace trail {
MANAGED_PUBLIC class Class1
{
// TODO: Add your methods for this class here.
};
}
I wanted to use MANAGED_PUBLIC instead of using public ref each and every time in whole project
You cannot do that. public ref is a context sensitive keyword. You cannot bury it down under a macro. C++/CLI compiler would process it differently than a regular compiler hence the macro outcome won't be public ref. You must type it everywhere.
You can use two macros:
#define MANAGED_PUB public
#define MANAGED_REF ref
MANAGED_PUB MANAGED_REF class Class1
{
// TODO: Add your methods for this class here.
};
You might try a compiler flag: -DMANAGED_PUBLIC="public ref" for your legacy code (quotes are stripped according to msdn).

passing object from c# to c++

I've been working on a prototype code application that runs in C# and uses classes and functions from older C++ code (in the form of an imported DLL). The code requirement is to pass in a class object to the unmanaged C++ DLL (from C#) and have it be stored/modified for retrieval later by the C# application. Here's the code I have so far...
Simple C++ DLL Class:
EXPORT_DLL int init(MyInitParams *initparams);
C++ DLL Functions:
struct MyInitParams {
public:
int _np;
int _nm;
int type;
double *CV_Weight;}
in c# DLL
[DllImport("NEWUSEMPC", CallingConvention = CallingConvention.Cdecl, EntryPoint = "init")]
public static extern int init(InitParams parameters);
in c# class
class InitParams
{
public int _np;
public int _nm;
public int type;
public double[] CV_Weight;}
If you own the code of the c++ dll it would be a lot more convenient for you to include it in your solution, and create an interop between c# and c++ using managed c++ as a translation layer. Be aware, that the managed c++ layer should only do the translation of data and invoke the native method, and literally nothing else, because managed c++ is designed only as a bridge between the native and managed world.
You can also use mixed debugger to check out what is happening in both managed and unmanaged code in debug to take a look on the variables, so that you can see what's missing.
I personally would discourage the use of platform invoke instead of an interop class, because the latter is a lot cleaner and is easier to maintain later on.

Using IDispatchImpl with an Unregistered Interface in an MFC+ATL EXE

I started the project as an MFC Application (for the GUI..), and later added support for ATL.
I then coded a simple ATL-COM object implementing a non registered dual interface using IDispatchImpl, with the 0xfff for Major and Minor, to tell ATL to load the TLB from the EXE.
I skip some details, but at the end, after some debugging I found that the CComTypeInfoHolder::GetTI implementation in atlcom.h was NOT trying to load the TLB from the EXE, but was searching it in the registry. Reason : a m_plibid variable was NOT corresponding to the DECLARE_LIBID macro use in my ATL::CAtlMfcModule declaration.
After some googling I found Bug: CAtlMfcModule::InitLibId() not called and added a call to InitLibId in my module CTOR.
Works fine, now.
Question: Is that a known bug? with a known fix? I am not confortable with my workaround of such an old bug. Is there another way of dealing with that?
UPDATE: additional information, as an answer states there is no bug...
IDispatchImpl Class:
By default, the IDispatchImpl class looks up the type information for
T in the registry. To implement an unregistered interface, you can use
the IDispatchImpl class without accessing the registry by using a
predefined version number. If you create an IDispatchImpl object that
has 0xFFFF as the value for wMajor and 0xFFFF as the value for wMinor,
the IDispatchImpl class retrieves the type library from the .dll file
instead of the registry.
Excerpt from CComTypeInfoHolder::GetTI Implementation in atlcom.h:
if (InlineIsEqualGUID( CAtlModule::m_libid, *m_plibid) &&
m_wMajor == 0xFFFF &&
m_wMinor == 0xFFFF ) {
TCHAR szFilePath[MAX_PATH];
DWORD dwFLen = ::GetModuleFileName(_AtlBaseModule.GetModuleInstance(), szFilePath, MAX_PATH);
[...]
hRes = LoadTypeLib(pszFile, &pTypeLib);
} else {
[...]
hRes = LoadRegTypeLib(*m_plibid, m_wMajor, m_wMinor, lcid, &pTypeLib);
So, it seems clear to me that there is an advertised behavior: use 0xffff for minor and major and ATL will try to load the typelib from module, not from registry, provided that your CAtlModule::m_libid is up todate. How is CAtlModule::m_libid expected to be be up to date? By using the DECLARE_LIBID macros. How does work that macro? by defining a static InitLibId function, which set up CAtlModule::m_libid.
The bug: when your module derives from ATL::CAtlMfcModule, the defined InitLibId function is NOT called (as ATL::CAtlMfcModule is not a class template)
You are correct, if you are using -1 for major/minor versions, then is is assumed that type information would be taken from the binary. This however does not work with MFC projects: DECLARE_LIBID only works up to CAtlMfcModule class but not its descendants.
A quick fix might be like this, in atlbase.h:
//class CAtlMfcModule :
// public ATL::CAtlModuleT<CAtlMfcModule>
template <typename T>
class CAtlMfcModuleT :
public ATL::CAtlModuleT<T>
and then in your project:
//class CMFCApplication1Module :
// public ATL::CAtlMfcModule
class CMFCApplication1Module :
public ATL::CAtlMfcModuleT<CMFCApplication1Module>
If you post it on MS Connect as a bug, you can leave a link here for others to go upvote the bug.

Simple singleton pattern - Visual C++ assertion failure

I'm recently programming a very simple logger class in Visual C++ 2010, but I have a problem. Everytime I run the program, a debug assertion failure appears.
Expression: _CrtIsValidHeapPointer(pUserData)
This is how my class looks like (basically it's only a little modified from an answer here C++ Singleton design pattern):
class Logger
{
public:
// Returns static instance of Logger.
static Logger& getInstance()
{
static Logger logger; // This is where the assertion raises.
return logger;
}
void logError(std::string errorText);
// Destructor.
~Logger();
private:
std::ofstream logFileStream;
// The constructor is private to prevent class instantiating.
Logger();
// The copy constructor and '=' operator need to be disabled.
Logger(Logger const&) { };
Logger& operator=(Logger other) { };
};
And the constructor is:
Logger::Logger()
: logFileStream(Globals::logFileName, std::ios_base::trunc)
{
// (Tries to open the file specified in Globals for (re)writing.)
}
I found out that I can solve it by using static variables or methods somehow, but I don't understand what's wrong with this code. Does anyone know, where the problem is?
EDIT: FYI, the failure raises when this code is called (for the first time):
Logger::getInstance().logError("hello");
EDIT 2: This is the definition of logFileName in Globals:
static const std::string logFileName = "errorLog.log";
My guess is that you're calling getInstance() from the constructor of another global variable, and encountering the infamous initialisation order fiasco - it's unspecified whether or not Globals::logFileName has been initialised before any globals in other translation units.
One fix is to use an old-school C string, which will be statically initialised before any global constructor is called:
static const char * logFileName = "errorLog.log";
Another possibility is to access it via a function:
static std::string logFileName() {return "errorLog.log";}
My favoured solution would be to remove the global instance altogether, and pass a reference to whatever needs it; but some might find that rather tedious, especially if you already have a large amount of code that uses the global.
C++/CLI is not standard C++ and plays by slightly different rules. Are you using C++/CLI managed code at all? (/clr compiler option?) This looks like a common problem when mixing C++ (unmanaged) code with C++/CLI (managed) code. It has to do with the way managed and unmanaged construction and destruction happens at program initialization and program exit. Removing the destructor works for me - can you do that in your Logger class?
For more details and possible workarounds:
http://www.codeproject.com/Articles/442784/Best-gotchas-of-Cplusplus-CLI
http://social.msdn.microsoft.com/Forums/vstudio/en-US/fa0e9340-619a-4b07-a86b-894358d415f6/crtisvalidheappointer-fails-on-globally-created-object-within-a-static-llibrary?forum=vcgeneral
http://forums.codeguru.com/showthread.php?534537-Memory-leaks-when-mixing-managed-amp-native-code&p=2105565

Possible C# 4.0 compiler error, can others verify?

Since I don't know exactly what part of it alone that triggers the error, I'm not entirely sure how to better label it.
This question is a by-product of the SO question c# code seems to get optimized in an invalid way such that an object value becomes null, which I attempted to help Gary with yesterday evening. He was the one that found out that there was a problem, I've just reduced the problem to a simpler project, and want verification before I go further with it, hence this question here.
I'll post a note on Microsoft Connect if others can verify that they too get this problem, and of course I hope that either Jon, Mads or Eric will take a look at it as well :)
It involves:
3 projects, 2 of which are class libraries, one of which is a console program (this last one isn't needed to reproduce the problem, but just executing this shows the problem, whereas you need to use reflector and look at the compiled code if you don't add it)
Incomplete references and type inference
Generics
The code is available here: code repository.
I'll post a description below of how to make the projects if you rather want to get your hands dirty.
The problem exhibits itself by producing an invalid cast in a method call, before returning a simple generic list, casting it to something strange before returning it. The original code ended up with a cast to a boolean, yes, a boolean. The compiler added a cast from a List<SomeEntityObject> to a boolean, before returning the result, and the method signature said that it would return a List<SomeEntityObject>. This in turn leads to odd problems at runtime, everything from the result of the method call being considered "optimized away" (the original question), or a crash with either BadImageFormatException or InvalidProgramException or one of the similar exceptions.
During my work to reproduce this, I've seen a cast to void[], and the current version of my code now casts to a TypedReference. In one case, Reflector crashes so most likely the code was beyond hope in that case. Your mileage might vary.
Here's what to do to reproduce it:
Note: There is likely that there are more minimal forms that will reproduce the problem, but moving all the code to just one project made it go away. Removing the generics from the classes also makes the problem go away. The code below reproduces the problem each time for me, so I'm leaving it as is.
I apologize for the escaped html characters in the code below, this is Markdown playing a trick on me, if anyone knows how I can rectify it, please let me know, or just edit the question
Create a new Visual Studio 2010 solution containing a console application, for .NET 4.0
Add two new projects, both class libraries, also .NET 4.0 (I'm going to assume they're named ClassLibrary1 and ClassLibrary2)
Adjust all the projects to use the full .NET 4.0 runtime, not just the client profile
Add a reference in the console project to ClassLibrary2
Add a reference in ClassLibrary2 to ClassLibrary 1
Remove the two Class1.cs files that was added by default to the class libraries
In ClassLibrary1, add a reference to System.Runtime.Caching
Add a new file to ClassLibrary1, call it DummyCache.cs, and paste in the following code:
using System;
using System.Collections.Generic;
using System.Runtime.Caching;
namespace ClassLibrary1
{
public class DummyCache<TModel> where TModel : new()
{
public void TriggerMethod<T>()
{
}
// Try commenting this out, note that it is never called!
public void TriggerMethod<T>(T value, CacheItemPolicy policy)
{
}
public CacheItemPolicy GetDefaultCacheItemPolicy()
{
return null;
}
public CacheItemPolicy GetDefaultCacheItemPolicy(IEnumerable<string> dependentKeys, bool createInsertDependency = false)
{
return null;
}
}
}
Add a new file to ClassLibrary2, call it Dummy.cs and paste in the following code:
using System;
using System.Collections.Generic;
using ClassLibrary1;
namespace ClassLibrary2
{
public class Dummy
{
private DummyCache<Dummy> Cache { get; set; }
public void TryCommentingMeOut()
{
Cache.TriggerMethod<Dummy>();
}
public List<Dummy> GetDummies()
{
var policy = Cache.GetDefaultCacheItemPolicy();
return new List<Dummy>();
}
}
}
Paste in the following code in Program.cs in the console project:
using System;
using System.Collections.Generic;
using ClassLibrary2;
namespace ConsoleApplication23
{
class Program
{
static void Main(string[] args)
{
Dummy dummy = new Dummy();
// This will crash with InvalidProgramException
// or BadImageFormatException, or a similar exception
List<Dummy> dummies = dummy.GetDummies();
}
}
}
Build, and ensure there are no compiler errors
Now try running the program. This should crash with one of the more horrible exceptions. I've seen both InvalidProgramException and BadImageFormatException, depending on what the cast ended up as
Look at the generated code of Dummy.GetDummies in Reflector. The source code looks like this:
public List<Dummy> GetDummies()
{
var policy = Cache.GetDefaultCacheItemPolicy();
return new List<Dummy>();
}
however reflector says (for me, it might differ in which cast it chose for you, and in one case Reflector even crashed):
public List<Dummy> GetDummies()
{
List<Dummy> policy = (List<Dummy>)this.Cache.GetDefaultCacheItemPolicy();
TypedReference CS$1$0000 = (TypedReference) new List<Dummy>();
return (List<Dummy>) CS$1$0000;
}
Now, here's a couple of odd things, the above crash/invalid code aside:
Library2, which has Dummy.GetDummies, performs a call to get the default cache policy on the class from Library1. It uses type inference var policy = ..., and the result is an CacheItemPolicy object (null in the code, but type is important).
However, ClassLibrary2 does not have a reference to System.Runtime.Caching, so it should not compile.
And indeed, if you comment out the method in Dummy that is named TryCommentingMeOut, you get:
The type 'System.Runtime.Caching.CacheItemPolicy' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime.Caching, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
Why having this method present makes the compiler happy I don't know, and I don't even know if this is linked to the current problem or not. Perhaps it is a second bug.
There is a similar method in DummyCache, if you restore the method in Dummy, so that the code again compiles, and then comment out the method in DummyCache that has the "Try commenting this out" comment above it, you get the same compiler error
OK, I downloaded your code and can confirm the problem as described.
I have not done any extensive tinkering with this, but when I run & reflector a Release build all seems OK (= null ref exception and clean disassembly).
Reflector (6.10.11) crashed on the Debug builds.
One more experiment: I wondered about the use of CacheItemPolicies so I replaced it with my own MyCacheItemPolicy (in a 3rd classlib) and the same BadImageFormat exception pops up.
The exception mentions : {"Bad binary signature. (Exception from HRESULT: 0x80131192)"}

Resources