Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: DLL convenience wrapper  (Read 19124 times)

0 Members and 1 Guest are viewing this topic.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
DLL convenience wrapper
« Reply #15 on: October 15, 2008, 01:43:16 pm »
Write your own class (or extract and adapt Ogre's one) ; all you need to know is the name of the 3 functions to call for each OS, and this can be found in Ogre's class.
Laurent Gomila - SFML developer

Core Xii

  • Jr. Member
  • **
  • Posts: 54
    • MSN Messenger - corexii@gmail.com
    • AOL Instant Messenger - Core+Xii
    • View Profile
DLL convenience wrapper
« Reply #16 on: October 15, 2008, 02:21:03 pm »
And, like I said, Ogre's is too entangled to the rest of the engine for me to extract.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
DLL convenience wrapper
« Reply #17 on: October 15, 2008, 02:40:55 pm »
What are you talking about ? The class is almost empty, except the 3 OS-specific calls you have to make. The rest is logging and error handling, which is straight-forward to remove.
Laurent Gomila - SFML developer

zarka

  • Jr. Member
  • **
  • Posts: 81
    • View Profile
DLL convenience wrapper
« Reply #18 on: October 15, 2008, 09:58:01 pm »
Quote from: "Core Xii"
Right but I'd need to link to Ogre. Bit of a big an engine to link to for one class.


umm as laurent has pointed out a lot of times.. this class is dead simple to rip out.. i did it in ~15min including a test run.

here it is btw.. one thing to remember though is that since this is slightly modified OGRE code it will fall into the LGPL license.

header file
Code: [Select]

#ifndef _DynLib_H__
#define _DynLib_H__

#include <string>
#include "sfml/System.hpp"

#if defined(SFML_SYSTEM_WINDOWS)
#    define DYNLIB_HANDLE hInstance
#    define DYNLIB_LOAD( a ) LoadLibraryExA( a, NULL, LOAD_WITH_ALTERED_SEARCH_PATH )
#    define DYNLIB_GETSYM( a, b ) GetProcAddress( a, b )
#    define DYNLIB_UNLOAD( a ) !FreeLibrary( a )

struct HINSTANCE__;
typedef struct HINSTANCE__* hInstance;

#elif defined(SFML_SYSTEM_LINUX)
#    define DYNLIB_HANDLE void*
#    define DYNLIB_LOAD( a ) dlopen( a, RTLD_LAZY | RTLD_GLOBAL)
#    define DYNLIB_GETSYM( a, b ) dlsym( a, b )
#    define DYNLIB_UNLOAD( a ) dlclose( a )

#elif defined(SFML_SYSTEM_MACOS)
#    define DYNLIB_HANDLE CFBundleRef
#    define DYNLIB_LOAD( a ) mac_loadExeBundle( a )
#    define DYNLIB_GETSYM( a, b ) mac_getBundleSym( a, b )
#    define DYNLIB_UNLOAD( a ) mac_unloadExeBundle( a )
#endif

namespace sf
{
class DynLib
    {
protected:
std::string mName;
std::string dynlibError(void);
    public:
        DynLib( const std::string& name );
        ~DynLib();
        void load();
        void unload();
const std::string& getName(void) const { return mName; }
        void* getSymbol( const std::string& strName ) const throw();
    protected:
        DYNLIB_HANDLE m_hInst;
    };
}

#endif




and the cpp file:

Code: [Select]

#include "DynLib.h"
#include <iostream>
#if defined(SFML_SYSTEM_WINDOWS)
#   define WIN32_LEAN_AND_MEAN
#   include <windows.h>
#endif

#if defined(SFML_SYSTEM_MACOS)
#   include "macPlugins.h"
#endif

namespace sf
{
    DynLib::DynLib( const std::string& name )
    {
        mName = name;
        m_hInst = NULL;
    }
    DynLib::~DynLib()
    {
    }
    void DynLib::load()
    {
std::string name = mName;
#if defined(SFML_SYSTEM_LINUX)
        // dlopen() does not add .so to the filename, like windows does for .dll
        if (name.substr(name.length() - 3, 3) != ".so")
           name += ".so";
#endif
        m_hInst = (DYNLIB_HANDLE)DYNLIB_LOAD( name.c_str() );
        if( !m_hInst )
            std::cerr << "Could not load dynamic library " << mName << ".  System Error: " << dynlibError() << "DynLib::load" ;
    }

    void DynLib::unload()
    {
        if( DYNLIB_UNLOAD( m_hInst ) )
{
            std::cerr << "Could not unload dynamic library " << mName << ".  System Error: " << dynlibError() << "DynLib::unload";
}

    }

    void* DynLib::getSymbol( const std::string& strName ) const throw()
    {
        return (void*)DYNLIB_GETSYM( m_hInst, strName.c_str() );
    }
    std::string DynLib::dynlibError( void )
    {
#if defined(SFML_SYSTEM_WINDOWS)
        LPVOID lpMsgBuf;
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
        std::string ret = (char*)lpMsgBuf;
        LocalFree( lpMsgBuf );
        return ret;
#elif defined(SFML_SYSTEM_LINUX)
        return std::string(dlerror());
#elif defined(SFML_SYSTEM_MACOS)
        return std::string(mac_errorBundle());
#else
        return std::string("");
#endif
    }

}



so now i saved you all 15min of work ;)
//Zzzarka

Core Xii

  • Jr. Member
  • **
  • Posts: 54
    • MSN Messenger - corexii@gmail.com
    • AOL Instant Messenger - Core+Xii
    • View Profile
DLL convenience wrapper
« Reply #19 on: October 16, 2008, 05:06:22 am »
If it works, thanks. I couldn't do this myself. OgreDynLib.h includes OgrePrerequisites.h, which in turn includes OgrePlatform.h, OgreStdHeaders.h and OgreMemoryAllocatorConfig.h; Which include a bunch of STL headers. Got much too entangled for me to handle.

zarka

  • Jr. Member
  • **
  • Posts: 81
    • View Profile
DLL convenience wrapper
« Reply #20 on: October 16, 2008, 10:44:54 am »
Quote from: "Core Xii"
If it works, thanks. I couldn't do this myself. OgreDynLib.h includes OgrePrerequisites.h, which in turn includes OgrePlatform.h, OgreStdHeaders.h and OgreMemoryAllocatorConfig.h; Which include a bunch of STL headers. Got much too entangled for me to handle.


You should never try to dig that deep at once. start by checking out the class definition and see what the class actually uses. it is quite obvious that this class uses very little of Ogres internal functions. oh and yes it works i played with it some more yesterday and as an example loaded up the functions SDL_SetError and SDL_GetError from sdl.dll and used called them and it worked :)

here is the way i did it:
1. fix obvius errors (like removing Ogre includes, inheritances, and preprocessor commands)
2. hit compile
3. fix errors (like Ogre::String and ogre log/exceptions)
4. goto 2 until no more errors
5. tests it out and fix runtime errors(actualy i never got any runtime errors.. i just had to figure out how to casts the void* returned from getSymbol to a usable function pointer)

common errors was
1. platform defines (sfml has these in it's system lib so i just switched to those
2. String (is a ogre typedef of std::string) so i replaced all String with std::string
3. exchanged all ogre exceptions and logger calls to std::cerr calls
4. it inherits from some kind of ogre allocator... which i do not know what it does and have no intentions to find out... so it got removed completely.. and i have noticed no errors.

learning how to refactor other peoples code is a great skill to know, especially if you want to start working as a programmer. (since changing/fixing other peoples code is what you will most likely do all day long ;) )
//Zzzarka

Core Xii

  • Jr. Member
  • **
  • Posts: 54
    • MSN Messenger - corexii@gmail.com
    • AOL Instant Messenger - Core+Xii
    • View Profile
DLL convenience wrapper
« Reply #21 on: October 16, 2008, 11:15:21 am »
I imagine. But I'm not really a programmer, more like an engineer. My talent lies in creating stuff, not understanding others' :roll:

Anyway, thank you for assisting me. I'm hoping a similar class finds its way into SFML so it'll be readily usable right away (not that there's anything wrong with your implementation). Until then, might just use this 8)