荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Deny (孤苦伶仃一个人,哈哈), 信区: Program
标  题: Dynamically loading classes from DLLs
发信站: 荔园晨风BBS站 (Tue Dec 25 19:50:57 2001), 转信

Dynamically loading classes from DLLs

------------------------------------------------------------------------
--------
This article was contributed by Jürgen Kraus, by courtesy of ProXima
Engineering Office.
Have you ever wondered whether there is a way to have an application
extrinsically load a DLL (e.g. via the LoadLibrary() function) which
exports classes so that the loader of the DLL can then use objects of
the class ?

This is basically no problem, the only thing that makes this a pain in
the [censored] are the 'C++ mangled names' of the methods in the DLL's
export section (e.g. '?CreateObject@CFrameDoc@@SGPAVCObject@@XZ'). The
simple trick get around this (and not using (D)COM) is: If you have (e.
g.) a class called CMyClass, declare it in the header file common to
both application and DLL:


#include ...

#ifdef _DLL // assume this is defined when we build the DLL
#define _DYNLINK __declspec( dllexport)
#else
#define _DYNLINK __declspec( dllimport)
#endif

class _DYNLINK CMyClass
{
public:
            CMyClass ();
    virtual ~CMyClass();

    void    DoSomethingUseful();
};

then, export a function from the DLL that returns a pointer to an
instance of CMyClass, let's call it 'CreateMyClass()' - it basically
should do 'return ( new CMyClass());'


#ifndef _DLL
typedef CMyClass* ( *PFNCREATEMYCLASS)();
#else
_DYNLINK CMyClass* CreateMyClass()
{
        return ( new CMyClass());
}
#endif


Also provide a function from the DLL that performs a 'delete' on the
object. Let's call it 'DeleteMyClass()' - it basically should do 'delete
 pObj;'. This function is necessary due to the fact that the CRT uses
different heaps and therefore different allocators for EXEs/DLLs, so
that you're just lucky if there's no crash...


#ifndef _DLL
typedef void ( *PFNDELETEMYCLASS)( CMyClass*);
#else
_DYNLINK void DeleteMyClass ( CMyClass* pObj)
{
        delete pObj;
}
#endif


Last but not least, we need a way to get access to the objects methods
without 'knowing' about the source code:


typedef void ( CMyClass::*PMYCLASSMETHOD)();
// the type created above ALWAYS points to a memer function of class
'CMyClass'
// which takes no arguments and returns nothing

#ifndef _DLL
typedef PMYCLASSMETHOD ( *PFNGETCLASSMETHOD)();
#else
_DYNLINK PMYCLASSMETHOD GetClassMethod ()
{
        return &CMyClass::DoSomethingUseful;
}
#endif

We also need a module definition file for our DLL. Remember: We use a
C interface to our DLL! (the 'PRIVATE' keyword instructs the linker
not to list the function in the DLL's import library).


   LIBRARY dynclass.dll
   EXPORTS
    CreateMyClass               @2 PRIVATE          ; object creation
    DeleteMyClass               @3 PRIVATE          ; object
destruction
    GetClassMethod              @4 PRIVATE          ; method access


In your application, load the DLL and get a pointer to 'CreateMyClass()'
 (error checking omitted for brevity)


PFNCREATEMYCLASS        pfnCreateMyClass;
PFNDELETEMYCLASS        pfnDeleteMyClass;
PFNGETCLASSMETHOD       pfnGetClassMethod;
PMYCLASSMETHOD          pDoSomethingUseful;
CMyClass* pMyClass;

HANDLE hDll;

hDll = LoadLibrary ( ...);

pfnCreateMyClass  = (PFNCREATEMYCLASS)  GetProcAddress ( hDll,
"CreateMyClass");
pfnDeleteMyClass  = (PFNDELETEMYCLASS)  GetProcAddress ( hDll,
"DeleteMyClass");
pfnGetClassMethod = (PFNGETCLASSMETHOD) GetProcAddress ( hDll,
"GetClassMethod");

// et voila - an instance of CMyClass!
  pMyClass = ( pfnCreateMyClass) ();

  pDoSomethingUseful = ( pfnGetClassMethod ());

  ( pMyClass->*pDoSomethingUseful) ();

  ( pfnDeleteMyClass ( pMyClass));

Outlook: This article just intends to demonstrate the technology 'how to
 do it'. There's much work to do if you want to use it in your
applications, e.g. creating just one function in the DLL that fills in a
 structure which holds all the function pointers you need, or even a
proxy class that does this automatically. Well, i'll keep this for a
future update of this article.


--
                                                              (    (
      如果我可以保留全部与你聊天的讯息,那么我会喜欢你。       )   )
      我保留了全部的讯息了吗?                                 (  (
      是的,我保留了。所以我喜欢你。                           ) )
                                                              ( )
  _______________________________________ ██▓███████_( ____________

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.1.201]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店