Skip to content

Commit

Permalink
Hack to make RCCpp work on Linux.
Browse files Browse the repository at this point in the history
We need to change the name of the library every time we call dlopen
because otherwise even after closing it dlopen returns the same handler.
  • Loading branch information
pamarcos committed Jun 26, 2014
1 parent 5b24910 commit 2ae5db3
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
29 changes: 26 additions & 3 deletions Source/Engine/RCCpp/RCCppUnix.cpp
@@ -1,4 +1,4 @@
//
//
// Copyright (c) 2008-2014 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down Expand Up @@ -40,7 +40,8 @@ RCCppUnix::RCCppUnix(Context* context) :
library_(NULL),
createObject_(NULL),
destroyObject_(NULL),
compiler_(new RCCppGppCompiler(context_))
compiler_(new RCCppGppCompiler(context_)),
fileSystem_(context_->GetSubsystem<FileSystem>())
{
}

Expand Down Expand Up @@ -84,7 +85,23 @@ void RCCppUnix::DestroyObject(RCCppObject *object)

bool RCCppUnix::LoadLib(const String& libraryPath)
{
if (library_ != NULL)
{
UnloadLib();
}
#ifdef __linux__
// Hack in case it's Linux. It seems dlopen caches the library name and in case
// the same library name is opened again (even after closing the library), it returns
// the same handler (memory address). Hence, every time we need to load the library we
// use a different name to avoid that happening.
static unsigned counter = 0;
String tmpLibraryPath = libraryPath + "." + String(counter++);
fileSystem_->Rename(libraryPath, tmpLibraryPath);
library_ = dlopen(tmpLibraryPath.CString(), RTLD_LAZY);
fileSystem_->Rename(tmpLibraryPath, libraryPath);
#else
library_ = dlopen(libraryPath.CString(), RTLD_LAZY);
#endif
if (library_ != NULL)
{
String name = GetFileName(libraryPath);
Expand All @@ -94,6 +111,7 @@ bool RCCppUnix::LoadLib(const String& libraryPath)
}
else
{
LOGERROR("Error loading library " + libraryPath + ": " + dlerror());
return false;
}
}
Expand All @@ -102,9 +120,14 @@ void RCCppUnix::UnloadLib()
{
if (library_ != NULL)
{
dlclose(library_);
if (dlclose(library_) != 0)
{
LOGERROR("Error closing library: " + String(dlerror()));
}
library_ = NULL;
mainObject_ = NULL;
createObject_ = NULL;
destroyObject_ = NULL;
}
}

Expand Down
2 changes: 2 additions & 0 deletions Source/Engine/RCCpp/RCCppUnix.h
Expand Up @@ -36,6 +36,7 @@ namespace Urho3D
class RCCppMainObject;
class RCCppObject;
class RCCppCompiler;
class FileSystem;

class URHO3D_API RCCppUnix : public RCCppImpl
{
Expand All @@ -57,6 +58,7 @@ class URHO3D_API RCCppUnix : public RCCppImpl
void* library_;
PCreateRCCppObject createObject_;
PDestroyRCCppObject destroyObject_;
FileSystem* fileSystem_;
};

}
Expand Down
6 changes: 6 additions & 0 deletions Source/Engine/RCCpp/RCCppWin.cpp
Expand Up @@ -103,6 +103,10 @@ void RCCppWin::DestroyObject(RCCppObject *object)

bool RCCppWin::LoadLib(const String& libraryPath)
{
if (library_ != NULL)
{
UnloadLib();
}
library_ = LoadLibrary(libraryPath.CString());
if (library_ != NULL)
{
Expand All @@ -124,6 +128,8 @@ void RCCppWin::UnloadLib()
FreeLibrary(library_);
library_ = NULL;
mainObject_ = NULL;
createObject_ = NULL;
destroyObject_ = NULL;

if (!oldLibPath_.Empty())
{
Expand Down

0 comments on commit 2ae5db3

Please sign in to comment.