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
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?
Damien LEFEVRE
Damien LEFEVRE 2017-1-18
Yes they are global, declared right after the includes, I just skipped that part in the snippet.
The d variable is a pointer of the QCoreApplication private class (QCoreApplicationPrivate) implementation. Qt uses public and private implementation for classes. The public interface doesn't or rarely change; the logic is implemented in the private class which can then change to provide bug fixes, etc, without breaking backward compatibility.
d->argv points to original argv. I stepped through the code to ensure they do not make a copy.
I agree with your statement, this is how memory management should work in a DLL. What I'm seeing does not make sense.

请先登录,再进行评论。

回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Write C Functions Callable from MATLAB (MEX Files) 的更多信息

标签

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by