Global static variable re-allocated in MEX file
1 次查看(过去 30 天)
显示 更早的评论
I wrote a mex file which loads a C++ library written using Qt framework. For the framework to work I need an instance of QCoreApplication.
Here's a snippet of the library:
QCoreApplication* pQApplication = nullptr;
static int argc = 1;
static char * argv[] = { "sharedlib.app", 0 };
SI_IMPEXP int SI_Load()
{
if (!QCoreApplication::instance())
{
QCoreApplication::addLibraryPath("C:/Windows/System32/Specim");
pQApplication = new QCoreApplication(argc, argv);
}
}
SI_IMPEXP int SI_Unload()
{
if (pQApplication)
{
delete pQApplication;
pQApplication = nullptr;
}
}
SI_IMPEXP int SI_Test()
{
qDebug() << "Test";
}
With the first MEX object instance I create, I test if QCoreApplication instance exists (SI_Load). If not I create one. With the last MEX object, I delete QCoreApplication instance (SI_Unload).
The mex file crashes when doing SI_Load --> SI_Unload --> SI_Load, so new QCoreApplication, delete QCoreApplication , new QCoreApplication.
I stepped into Qt source code.
if (d->argc) {
static const char *procName = d->argv[0];
if (qstrcmp(procName, d->argv[0]) != 0) {
// clear the cache if the procname changes, so we reprocess it.
QCoreApplicationPrivate::clearApplicationFilePath();
procName = d->argv[0];
}
}
The problem is at line
static const char *procName = d->argv[0];
procName is initialized with the address of "sharedlib.app" in the argv array at the first function call.
argv is a global static variable, so you wouldn't expect it to be re-allocated. But it is.
I checked the argv and argv[0] addresses at the different functions and is an example of what I get.
- SI_Load: argv = 0x000007fee3fd7008 {0x000007fee3fa2c00 "sharedlib.app", 0x0000000000000000 NULL}
- SI_Test: argv = 0x000007fee3fd7008 {0x000007fee3fa2c00 "sharedlib.app", 0x0000000000000000 NULL}
- SI_Unload argv = 0x000007fee3fd7008 {0x000007fee3fa2c00 "sharedlib.app", 0x0000000000000000 NULL}
- SI_Load argv = 0x000007fee3 96 7008 {0x000007fee3 93 2c00 "sharedlib.app", 0x0000000000000000 NULL} <-- new argv allocation – QcoreApplication constructor will crash since the already initialized static const char procName points to old memory.
Each of these call are run from the same thread and same process ID. argv is reallocated only after SI_Unload has returned.
The reason why I'm asking this forum is because I've made some test application to test my module in a non Qt environment, and I don't have any errors. I've tested creating and deleting the QCoreApplication over 100 times with no error.
Matlab seems to be written with Java and I'm not familiar with it.
Has anyone encountered this kind of issue?
2 个评论
James Tursa
2017-1-17
Are you sure these are global variables (i.e., at the top level)? Or is your posted code snippet inside of other code that we can't see? I don't see how a loaded DLL routine can change the address of a top level global variable mid-stream, unless you unload and then reload the DLL. Also, it isn't clear how the argv variable as a calling argument becomes d->argv in the function. What is d and how is it related to the original passed in argv?
回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!