summaryrefslogtreecommitdiffstats
path: root/include/astra
diff options
context:
space:
mode:
Diffstat (limited to 'include/astra')
-rw-r--r--include/astra/AstraObjectManager.h2
-rw-r--r--include/astra/Fourier.h2
-rw-r--r--include/astra/Singleton.h28
-rw-r--r--include/astra/Utilities.h3
4 files changed, 24 insertions, 11 deletions
diff --git a/include/astra/AstraObjectManager.h b/include/astra/AstraObjectManager.h
index ad89c2a..9faecbe 100644
--- a/include/astra/AstraObjectManager.h
+++ b/include/astra/AstraObjectManager.h
@@ -60,7 +60,7 @@ public:
};
-class CAstraIndexManager : public Singleton<CAstraIndexManager> {
+class _AstraExport CAstraIndexManager : public Singleton<CAstraIndexManager> {
public:
CAstraIndexManager() : m_iLastIndex(0) { }
diff --git a/include/astra/Fourier.h b/include/astra/Fourier.h
index ff26f82..68f9f38 100644
--- a/include/astra/Fourier.h
+++ b/include/astra/Fourier.h
@@ -76,7 +76,7 @@ namespace astra {
}
.
*/
-void cdft(int n, int isgn, float32 *a, int *ip, float32 *w);
+_AstraExport void cdft(int n, int isgn, float32 *a, int *ip, float32 *w);
}
diff --git a/include/astra/Singleton.h b/include/astra/Singleton.h
index a256187..9d3c088 100644
--- a/include/astra/Singleton.h
+++ b/include/astra/Singleton.h
@@ -45,11 +45,7 @@ class Singleton {
public:
// constructor
- Singleton() {
- assert(!m_singleton);
- int offset = (uintptr_t)(T*)1 - (uintptr_t)(Singleton<T>*)(T*)1;
- m_singleton = (T*)((uintptr_t)this + offset);
- };
+ Singleton() { }
// destructor
virtual ~Singleton() {
@@ -57,15 +53,17 @@ class Singleton {
m_singleton = 0;
}
+ static void construct();
+
// get singleton
static T& getSingleton() {
if (!m_singleton)
- m_singleton = new T();
+ construct();
return *m_singleton;
}
static T* getSingletonPtr() {
if (!m_singleton)
- m_singleton = new T();
+ construct();
return m_singleton;
}
@@ -76,11 +74,23 @@ class Singleton {
};
-#define DEFINE_SINGLETON(T) template<> T* Singleton<T >::m_singleton = 0
+// We specifically avoid defining construct() in the header.
+// That way, the call to new is always executed by code inside libastra.
+// This avoids the situation where a singleton gets created by a copy
+// of the constructor linked into an object file outside of libastra, such
+// as a .mex file, which would then also cause the vtable to be outside of
+// libastra. This situation would cause issues when .mex files are unloaded.
+
+#define DEFINE_SINGLETON(T) \
+template<> void Singleton<T >::construct() { assert(!m_singleton); m_singleton = new T(); } \
+template<> T* Singleton<T >::m_singleton = 0
+
// This is a hack to support statements like
// DEFINE_SINGLETON2(CTemplatedClass<C1, C2>);
-#define DEFINE_SINGLETON2(A,B) template<> A,B* Singleton<A,B >::m_singleton = 0
+#define DEFINE_SINGLETON2(A,B) \
+template<> void Singleton<A,B >::construct() { assert(!m_singleton); m_singleton = new A,B(); } \
+template<> A,B* Singleton<A,B >::m_singleton = 0
} // end namespace
diff --git a/include/astra/Utilities.h b/include/astra/Utilities.h
index 8d7c44d..22adfe2 100644
--- a/include/astra/Utilities.h
+++ b/include/astra/Utilities.h
@@ -85,6 +85,9 @@ _AstraExport std::string doubleToString(double f);
template<typename T>
_AstraExport std::string toString(T f);
+
+_AstraExport void splitString(std::vector<std::string> &items, const std::string& s, const char *delim);
+
}