Dynamically loading a Mac OS X library bundle (framework) written in Qt
-
I have two projects: a Qt Mac OS X library bundle (framework), and an Xcode written C++ console application that should dynamically load the library. The Qt Mac OS X library bundle project looks like this:
TestFramework.pro
@
QT -= guiTARGET = TestFramework
TEMPLATE = libCONFIG *= lib_bundle
CONFIG -= app_bundleDEFINES += TESTFRAMEWORK_LIBRARY
SOURCES += TestFramework.cpp
HEADERS += TestFramework.h
TestFramework_global.h@
TestFramework_global.h
@
#ifndef TESTFRAMEWORK_GLOBAL_H
#define TESTFRAMEWORK_GLOBAL_H#include <QtCore/qglobal.h>
#if defined(TESTFRAMEWORK_LIBRARY)
define TESTFRAMEWORKSHARED_EXPORT Q_DECL_EXPORT
#else
define TESTFRAMEWORKSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // TESTFRAMEWORK_GLOBAL_H
@TestFramework.h
@
#ifndef TESTFRAMEWORK_H
#define TESTFRAMEWORK_H#include "TestFramework_global.h"
int TESTFRAMEWORKSHARED_EXPORT magicNumber();
#endif // TESTFRAMEWORK_H
@TestFramework.cpp
@
#include "TestFramework.h"int magicNumber()
{
return 5; // return an arbitrary magic number
}
@The Xcode console application has the following source:
main.cpp
@
#include <string>
#include <iostream>
#include <dlfcn.h>using namespace std;
int main (int argc, const char * argv[])
{
const string binaryFilePath = "PATH_TO_THE_TEST_FRAMEWORK_LIBRARY_BUNLE/TestFramework.framework/TestFramework";void* binaryHandle = dlopen( binaryFilePath.c_str(), RTLD_NOW | RTLD_LOCAL ); if ( binaryHandle != NULL ) { cout << "library successfully loaded"; void* functionPointer = dlsym( binaryHandle, "magicNum" ); if ( functionPointer == NULL ) { count << "failed to obtain pointer to the function exposed by the library"; } dlclose( binaryHandle ); } else { cout << "failed to load library"; } return 0;
}
@The console application fails to load the library bundle e.g. the library that is contained in the library bundle.
What seems strage is that when the TestFramework library bundle is built the actual library contained in the bundle shows in Mac OS X Finder application as executable. When I saw this, I thought that either qmake build system hasn't build the library bundle correctly, or my TestFramework.pro file is missing something. I started looking for other prebuilt framework samples - the Qt frameworks for instance. The Qt*.framework library bundles contain a binary file that is seen by Finder as a document file( a blank white file icon ), not as an executable file. When I execute the console application using:
@
const string binaryFilePath = "/Library/Frameworks/QtCore.framework/QtCore";
@the library gets successfully loaded.
What is wrong with qmake/TestFramework.pro a correct library bundle is not generated?