У меня есть код C ++ / SDL 1.2, написанный прибл. 10 лет назад кем-то еще, что я хотел бы скомпилировать и запустить. Код предназначался для компиляции как для Win32, так и для Nintendo DS с использованием потоков miniGW + posix, SDL 1.2, SDL_Image и нескольких других библиотек и g ++ с make. Я попытался удалить любые связанные с miniGW SDL 1.2, включая пути и пути ссылок в различных используемых make-файлах, и заменить их на то, что я считаю правильным эквивалентом для SDL 1.2 на двух * NIX-основанных платформах, которые я пытался повторить. -компиляция в (Mac OS X & Raspbian) на основе вывода из sdl-config.
По большей части это, похоже, прошло успешно, я исправил некоторые незначительные проблемы из-за того, что имена файлов заголовков не использовали то же самоев качестве операторов включения в коде, и у меня осталась лишь небольшая часть оставшихся ошибок компиляции, которые появляются, связанные с потоками POSIX.
Исходный Makefile передает -lpthreadGC1
в g ++. Любые предложения по первопричине или как устранить?
g++ -c [...] Abortable.cpp
In file included from Abortable.cpp:14:
In file included from ./ThreadSafeContainer.h:15:
./ThreadSafe.h:64:54: error: member reference type 'ThreadSafe::ThreadId' (aka '_opaque_pthread_t *') is a pointer; did you mean to use '->'?
bool is_me(const ThreadId id) const { return me().p == id.p; }
~~~~^
->
./ThreadSafe.h:64:55: error: no member named 'p' in '_opaque_pthread_t'
bool is_me(const ThreadId id) const { return me().p == id.p; }
~~~~ ^
./ThreadSafe.h:64:62: error: member reference type 'const ThreadSafe::ThreadId' (aka '_opaque_pthread_t *const') is a pointer; did you mean to use '->'?
bool is_me(const ThreadId id) const { return me().p == id.p; }
~~^
->
./ThreadSafe.h:64:63: error: no member named 'p' in '_opaque_pthread_t'
bool is_me(const ThreadId id) const { return me().p == id.p; }
~~ ^
In file included from Abortable.cpp:14:
./ThreadSafeContainer.h:93:57: error: member reference type 'const ThreadSafeContainer::ThreadId' (aka '_opaque_pthread_t *const') is a pointer; did you mean to use '->'?
typename ContainerType::iterator rval = m_map.find(myid.p);
~~~~^
->
./ThreadSafeContainer.h:93:58: error: no member named 'p' in '_opaque_pthread_t'
typename ContainerType::iterator rval = m_map.find(myid.p);
~~~~ ^
./ThreadSafeContainer.h:101:33: error: member reference type 'const ThreadSafeContainer::ThreadId' (aka '_opaque_pthread_t *const') is a pointer; did you mean to use '->'?
m_map.insert(make_pair(myid.p,CNT()));
~~~~^
->
./ThreadSafeContainer.h:101:34: error: no member named 'p' in '_opaque_pthread_t'
m_map.insert(make_pair(myid.p,CNT()));
~~~~ ^
Abortable.cpp:580:15: warning: 'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to true [-Wtautological-undefined-compare]
my_assert(this != 0);
^~~~ ~
./MyAssert.h:23:31: note: expanded from macro 'my_assert'
#define my_assert(EX) (void)((EX) || (assert_failed(#EX, __FILE__, __LINE__), 0))
^~
1 warning and 8 errors generated.
make: *** [Abortable.o] Error 1
/*---------------------------------------------------------------------------*
* ThreadsafeContainer.h *
*---------------------------------------------------------------------------*/
#ifndef THREADSAFECONTAINER_H
#define THREADSAFECONTAINER_H
/*------------*
* Used units *
*------------*/
#include <map>
#include "ThreadSafe.h"
/*-----------------*
* Types & objects *
*-----------------*/
/**
*
* thread-safe object
*
* declare one static object ThreadSafeContainer<MyObject>, which is the
* global, thread-protected container for the MyObject objects
*
* there is 1 and only 1 MyObject object per thread
*
*
*
*/
template <class CNT>
class ThreadSafeContainer : public ThreadSafe
{
public:
typedef typename ThreadSafe::ThreadId ThreadId;
typedef std::map<void *,CNT> ContainerType;
typedef typename ContainerType::const_iterator const_iterator;
/**
* protected per-thread access method
*/
CNT &get()
{
return find_or_create();
}
/**
* protected per-thread access method (constant)
*/
const CNT &get() const
{
ThreadSafeContainer *nonconst_hack = (ThreadSafeContainer*)this;
return nonconst_hack->find_or_create();
}
/**
* unprotected start iterator. use cs_start/cs_end
* to protect the begin/end loop
*/
const_iterator begin() const
{
return m_map.begin();
}
/**
* unprotected end iterator. use cs_start/cs_end
* to protect the begin/end loop
*/
const_iterator end() const
{
return m_map.end();
}
private:
CNT &find_or_create()
{
const ThreadId myid = me();
cs_start();
typename ContainerType::iterator rval = m_map.find(myid.p);
if (rval == m_map.end())
{
// not found (first call to get() from this thread): create one
// in thread safe mode (list is shared by all threads)
std::pair<typename ContainerType::iterator, bool> success =
m_map.insert(make_pair(myid.p,CNT()));
// update size while in thread protected context
m_size = m_map.size();
rval = success.first;
}
cs_end();
return rval->second;
}
mutable ContainerType m_map;
};
#endif /* -- End of unit, add nothing after this #endif -- */
/*---------------------------------------------------------------------------*
* ThreadSafe.h *
*---------------------------------------------------------------------------*/
#ifndef THREADSAFE_H
#define THREADSAFE_H
/*------------*
* Used units *
*------------*/
#include "MyAssert.h"
#include <pthread.h>
#include <strings.h>
/*-----------------*
* Types & objects *
*-----------------*/
/**
*
* frame object for mutex support
*
*
*
*/
class ThreadSafe
{
public:
typedef pthread_t ThreadId;
/**
* critical section start
*/
void cs_start() const
{
pthread_mutex_lock(&m_creation_mutex);
}
/**
* critical section end
*/
void cs_end() const
{
pthread_mutex_unlock(&m_creation_mutex);
}
/**
* me
*/
inline ThreadId me() const { return pthread_self(); }
/**
* check if my id
*/
bool is_me(const ThreadId id) const { return me().p == id.p; }
/**
* @return number of items
*/
int size() const
{
return m_size;
}
~ThreadSafe()
{
pthread_mutex_destroy(&m_creation_mutex);
}
protected:
ThreadSafe() : m_size(0)
{
bool mutex_init_failure = pthread_mutex_init(&m_creation_mutex,NULL) != 0;
if (mutex_init_failure)
{
// force assertion failure with an intelligible message
//
// note: if (x) { my_assert(!x); } construction needed
// instead of direct my_assert(!x); because of NDEBUG mode
// (my_assert = empty macro and thus x would be unused)
mutex_init_failure = false;
my_assert(mutex_init_failure);
}
}
int m_size;
private:
mutable pthread_mutex_t m_creation_mutex;
};
#endif /* -- End of unit, add nothing after this #endif -- */```