15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Exporting classes

Lin Sebastian Kayser -- 100532.2621@compuserve.com
Saturday, February 10, 1996

Jean,

there were some answers to your questions but I think they were either a little
bit overkill or did not make the whole thing clear.

The easiest way I found for exporting classes is an approach similar to the
first answer that came but withour all that proxy stuff which you normally don't
need.

When creating a header file define the following macro:

#ifdef _MYDLL_BUILD
  #define MYDLL_DECL __declspec(dllexport)
#else
  #define MYDLL_DECL __declspec(dllimport)

Note the __declspec(dllimport) which allows the compiler to apply some
optimizations. _MYDLL_BUILD and MYDLL_DECL must be unique to each DLL.

Now you can export classes and/or functions by just using your MYDLL_DECL macro:

MYDLL_DECL void Foo();

class MYDLL_DECL CFoo : public CFooFoo
{

// just your declarations as usual

}

In your build settings you set the additional define _MYDLL_BUILD for compiling
your DLL. So each class will get exported through the __declspec(dllexport)
declaration.

When you use the DLL since there is no _MYDLL_BUILD defined you will get the
__declspec(dllimport) declaration which tells the compiler that you are about to
use a class in a DLL an allows it to optimize on it.

I am not quite sure about the AFX_CLASS_EXP approach. As far as I know there
are some problems when using a DLL from another DLL. But I could be mistaken on
this. The approach above described works reliably for me and is not much work.

Regards Lin @ Lizard Software, Germany





Mike Blaszczak -- mikeblas@interserv.com
Monday, February 12, 1996

On 10 Feb 96, Lin Sebastian Kayser <100532.2621@compuserve.com> wrote:
>When creating a header file define the following macro:
>
>#ifdef _MYDLL_BUILD
>  #define MYDLL_DECL __declspec(dllexport)
>#else
>  #define MYDLL_DECL __declspec(dllimport)
>
>Note the __declspec(dllimport) which allows the compiler to apply some
>optimizations. _MYDLL_BUILD and MYDLL_DECL must be unique to each DLL.

You don't usually need to do this because MFC has already done it for you.  
You can use AFX_CLASS_EXPORT, AFX_API_EXPORT, and AFX_CLASS_EXPORT.  These 
are all #defined in AFXVER_.H.

They're documented in my book, I'm sure.  They're documented in Tech Note 33, 
I think.

.B ekiM
--
TCHAR szDisc[] = _T("These words are my own; I do not speak for Microsoft.");




Vincent Mascart -- 100425.1337@compuserve.com
Monday, February 12, 1996

[Mini-digest: 2 responses]

You should read the technical note 33 (Visual C++ Books/MFC 4.0/MFC Technical
notes/MFC Technical notes Index/TN0033).

>>I am not quite sure about the AFX_CLASS_EXP approach. As far as I know there
>>are some problems when using a DLL from another DLL. But I could be mistaken
on
>>this. The approach above described works reliably for me and is not much work.

use the AFX_EXT_DATA, AFX_EXT_DATADEF, AFX_EXT_CLASS, AFX_EXT_API macro to
export your stuff. This works very well, including with DLL using other DLL.

Vincent Mascart
Little Indian sprl
100425.1337@compuserve.com



Regards Lin @ Lizard Software, Germany




-----From: Ken Freeman 

mikeblas@interserv.com wrote:
> 
> On 10 Feb 96, Lin Sebastian Kayser <100532.2621@compuserve.com> wrote:
> >When creating a header file define the following macro:
> >
> >#ifdef _MYDLL_BUILD
> >  #define MYDLL_DECL __declspec(dllexport)
> >#else
> >  #define MYDLL_DECL __declspec(dllimport)
> >
> >Note the __declspec(dllimport) which allows the compiler to apply some
> >optimizations. _MYDLL_BUILD and MYDLL_DECL must be unique to each DLL.
> 
> You don't usually need to do this because MFC has already done it for you.
> You can use AFX_CLASS_EXPORT, AFX_API_EXPORT, and AFX_CLASS_EXPORT.  These
> are all #defined in AFXVER_.H.
> 
> They're documented in my book, I'm sure.  They're documented in Tech Note 33,
> I think.
> 
> .B ekiM

Mike, I think the standard recommendation is to use AFX_EXT_CLASS when
defining an extension class.  This resolves to __declspec(dllexport)
(same as AFX_CLASS_EXPORT) when _AFXEXT is defined and __declspec(dllimport)
when it isn't.  If you just use AFX_CLASS_EXPORT, you'll probably get
some unresolved entry points at link time (usually on the runtime class
-- see Q131946 in MSKB).

The problem with this approach is that it doesn't work well when
you have several layers of MFC extension libraries.  If lib1 exports a 
class declared with AFX_EXT_CLASS (or AFX_CLASS_EXPORT), lib2 cannot import
that class since AFX_EXT_CLASS will be defined as __declspec(dllexport) 
instead of __declspec(dllimport).

The important thing is that the class be declared with dllexport when
building the DLL and with dllimport when using it.  If you have multiple
layers of DLLs, the easiest way to do that is to define a different
macro as Lin Kayser described above.

Ken



Lin Sebastian Kayser -- 100532.2621@compuserve.com
Tuesday, February 13, 1996

>>> Quote B. ekiM ---------------------------------------
You don't usually need to do this because MFC has already done it for you.  
You can use AFX_CLASS_EXPORT, AFX_API_EXPORT, and AFX_CLASS_EXPORT.  These 
are all #defined in AFXVER_.H.
<<< -----------------------------------------------------

"Usually" in this case means as long as you don't have one extension DLL
dependent on another.

>>> Quote B. ekiM ---------------------------------------
They're documented in my book, I'm sure.  They're documented in Tech Note 33, 
I think.
<<< -----------------------------------------------------

Did not read your book (could you give us the title I'd like to check it out)

[Moderator's note: Look in the MFC FAQ. ]

did read Technote 33 though. Here's what I found:

>>> Technote 33 -----------------------------------------

Limitations of _AFXEXT
You can use the _AFXEXT pre-processor symbol for your extension DLLs as long as
you do not have multiple layers of extension DLLs. If you have extension DLLs
which call or derive from classes in your own extension DLLs, which then derive
from the MFC classes, you must use your own preprocessor symbol to avoid
ambiguity.
The problem is that in Win32, you must explicitly declare any data as
__declspec(dllexport) if it is to be exported from a DLL, and
__declspec(dllimport) if it is to be imported from a DLL. When you define
_AFXEXT, the MFC headers make sure that AFX_EXT_CLASS is defined correctly.
When you have multiple layers, one symbol such as AFX_EXT_CLASS is not
sufficient, since an extension DLL may be exporting new classes as well as
importing other classes from another extension DLL. In order to deal with this
problem, use a special pre-processor symbol which indicates that you are
building the DLL itself vs. using the DLL.

<<< -----------------------------------------------------

Since this limitation exists I just made a habit out of declaring my own
preprocessor symbols. Relieves me from thinking about potential errors when
including a new dll in my project. Don't like thinking too much :)

Regards

Lin @ Lizard Software, Germany









| Вернуться в корень Архива |