I have a DLL project that I need to export a data variable from. I have
defined the variable in a .cpp file in the project like this

//C++ file (DLL Project)

class MYPROJ_API data_type
{
//Impl here ...
};

MYPROJ_API data_type exported_data;



//header file (project that consumes DLL)
extern MYPROJ_API data_type exported_data ;


where MYPROJ_API is amacro that handles declspec import/export

I checked the DLL project to ensure that the symbols are exported
correctly in the generated library - and they all are there - including
the exported data - yet when I try to build the other dependent project,
I am getting linkage errors (unresolved externals).

BTW, I have checked my library paths etc, and all is in order - anyone
come accross this before? - what am I missing?

Re: exporting data from a dll - unresolved externals by Klueless

Klueless
Mon Jan 07 22:39:42 CST 2008

"2b|!2b==?" <user@domain.invalid> wrote in message news:_9udncYmgLGlah_anZ2dnUVZ8uWdnZ2d@bt.com...
> //header file (project that consumes DLL)
> extern MYPROJ_API data_type exported_data ;
> I am getting linkage errors (unresolved externals).

Did you "#include" this DLL header file exporting the symbols
somewhere suitable in your consumer project (e.g. stdafx.h)?




Re: exporting data from a dll - unresolved externals by user

user
Mon Jan 07 22:45:14 CST 2008



Klueless wrote:

> "2b|!2b==?" <user@domain.invalid> wrote in message news:_9udncYmgLGlah_anZ2dnUVZ8uWdnZ2d@bt.com...
>
>>//header file (project that consumes DLL)
>>extern MYPROJ_API data_type exported_data ;
>>I am getting linkage errors (unresolved externals).
>
>
> Did you "#include" this DLL header file exporting the symbols
> somewhere suitable in your consumer project (e.g. stdafx.h)?
>
>
>
Naturally ....

Re: exporting data from a dll - unresolved externals by Klueless

Klueless
Tue Jan 08 01:37:14 CST 2008

"2b|!2b==?" <user@domain.invalid> wrote in message news:X-WdnWuy3PBHYh_anZ2dnUVZ8tbinZ2d@bt.com...
>> Did you "#include" this DLL header file exporting the symbols
>> somewhere suitable in your consumer project (e.g. stdafx.h)?
> Naturally ....

OK, here are a few follow up ideas:
(1) Make sure the "#include"d DLL header file is actually being found
by the consumer project. There is an option in VS2005 project settings
C/C++, Advanced, "Show Includes" which you can temporarily turn on.
It could be '#include "DllExports.h"' is working fine in your DLL directory,
but you need to use '#include "..\MyDll\DllExports.h"' in your consumer
project code.
(2) You should mave a minimal working MyConsumer/MyDll solution
lying around somewhere. (If not, VS2005 should let you create one
easily enough.) Make a copy of that solution. Copy and paste one of
the alleged undefined definitions into your minimal MyDll and reference
it in MyConsumer. It ought to still build. If not, isolate the problem in
this minimal context. If it does, then there is something different between
what you are doing in the minimal solution and what you are doing in
your original consumer/dll solution. Figure out the difference.
(3) It wouldn't hurt to put the "Dll.lib" in the Linker, Input, "Additional Dependencies",
just to be sure.




Re: exporting data from a dll - unresolved externals by Giovanni

Giovanni
Tue Jan 08 03:43:42 CST 2008


"2b|!2b==?" <user@domain.invalid> ha scritto nel messaggio
news:_9udncYmgLGlah_anZ2dnUVZ8uWdnZ2d@bt.com...
>I have a DLL project that I need to export a data variable from. I have
>defined the variable in a .cpp file in the project like this
>
> //C++ file (DLL Project)
>
> class MYPROJ_API data_type
> {
> //Impl here ...
> };

You are exporting a C++ class.
Are you using the same compiler version to build the DLL and the client of
your DLL?

> MYPROJ_API data_type exported_data;

Instead of exporting the class instance, you may try to export a global
function which returns a pointer to the class instance, something like this:

data_type globalData;

MYPROJ_API data_type * GetExportedData(void)
{
return &globalData;
}

So the DLL client could call GetExportedData() to access the class instance.

Giovanni



Re: exporting data from a dll - unresolved externals by user

user
Tue Jan 08 07:33:56 CST 2008



Giovanni Dicanio wrote:
> "2b|!2b==?" <user@domain.invalid> ha scritto nel messaggio
> news:_9udncYmgLGlah_anZ2dnUVZ8uWdnZ2d@bt.com...
>
>>I have a DLL project that I need to export a data variable from. I have
>>defined the variable in a .cpp file in the project like this
>>
>>//C++ file (DLL Project)
>>
>>class MYPROJ_API data_type
>>{
>> //Impl here ...
>>};
>
>
> You are exporting a C++ class.
> Are you using the same compiler version to build the DLL and the client of
> your DLL?
>

Erm, Yes ...

>
>>MYPROJ_API data_type exported_data;
>
>
> Instead of exporting the class instance, you may try to export a global
> function which returns a pointer to the class instance, something like this:
>
> data_type globalData;
>
> MYPROJ_API data_type * GetExportedData(void)
> {
> return &globalData;
> }
>
> So the DLL client could call GetExportedData() to access the class instance.
>

Good idea (although it is a work around), but it means I'll have to
refactor a lot of existing code I have already written. Is there a
TECHNICAL reason why I can't use a class that has been exported ?


> Giovanni
>
>

Re: exporting data from a dll - unresolved externals by Ben

Ben
Tue Jan 08 09:22:36 CST 2008


"2b|!2b==?" <user@domain.invalid> wrote in message
news:_9udncYmgLGlah_anZ2dnUVZ8uWdnZ2d@bt.com...
>I have a DLL project that I need to export a data variable from. I have
>defined the variable in a .cpp file in the project like this
>
> //C++ file (DLL Project)
>
> class MYPROJ_API data_type
> {
> //Impl here ...
> };
>
> MYPROJ_API data_type exported_data;
>
>
>
> //header file (project that consumes DLL)
> extern MYPROJ_API data_type exported_data ;

It looks to me like the type is incomplete here, because the class
declaration isn't seen from the header file.

>
>
> where MYPROJ_API is amacro that handles declspec import/export

dllexport of C++ classes is a bad idea. Optimally DLLs should only export
functions. You can pass around pointers to objects as long as they are
accessed through virtual functions (the client should only see an interface
definition with pure virtual functions and no data). Also memory should
always be freed in the same module that allocated it.

>
> I checked the DLL project to ensure that the symbols are exported
> correctly in the generated library - and they all are there - including
> the exported data - yet when I try to build the other dependent project, I
> am getting linkage errors (unresolved externals).
>
> BTW, I have checked my library paths etc, and all is in order - anyone
> come accross this before? - what am I missing?



Re: exporting data from a dll - unresolved externals by user

user
Tue Jan 08 10:16:25 CST 2008



Ben Voigt [C++ MVP] wrote:

> "2b|!2b==?" <user@domain.invalid> wrote in message
> news:_9udncYmgLGlah_anZ2dnUVZ8uWdnZ2d@bt.com...
>
>>I have a DLL project that I need to export a data variable from. I have
>>defined the variable in a .cpp file in the project like this
>>
>>//C++ file (DLL Project)
>>
>>class MYPROJ_API data_type
>>{
>> //Impl here ...
>>};
>>
>>MYPROJ_API data_type exported_data;
>>
>>
>>
>>//header file (project that consumes DLL)
>>extern MYPROJ_API data_type exported_data ;
>
>
> It looks to me like the type is incomplete here, because the class
> declaration isn't seen from the header file.
>

Not so. I kept the snippet simple for brevity sake. All other things
like library paths, pre-processor defines etc are taken as assumed -
(otherwise I will end up posting code for entire soln).

>
>>
>>where MYPROJ_API is amacro that handles declspec import/export
>
>
> dllexport of C++ classes is a bad idea. Optimally DLLs should only export
> functions. You can pass around pointers to objects as long as they are
> accessed through virtual functions (the client should only see an interface
> definition with pure virtual functions and no data). Also memory should
> always be freed in the same module that allocated it.
>
>

Once again, your assumptions are wrong. I kept the code snnipet I posted
here to a bare minimum for the previouslt stated reasons. the library is
much more 'complicated' than I let on - what I pasted here was the bare
bones that represented the salient features of the problem.

The DLL is a shared memory library - consequently, I cannot use any
virtual functions - as vtable fptrs will be meaningless in another
process space.

Re: exporting data from a dll - unresolved externals by Giovanni

Giovanni
Tue Jan 08 10:23:46 CST 2008


"2b|!2b==?" <user@domain.invalid> ha scritto nel messaggio
news:9_OdnbzImKJZ5h7anZ2dnUVZ8uadnZ2d@bt.com...

> Good idea (although it is a work around), but it means I'll have to
> refactor a lot of existing code I have already written. Is there a
> TECHNICAL reason why I can't use a class that has been exported ?

Frankly speaking, if I have to build a Win32 DLL, I tend to export a
C-interface. The DLL can be written in C++, of course, but the *interface*
is just plain C.
(Note that also FMOD, an important audio library, does something like this,
at least for FMOD3: C-interface DLL, and I think C++ implementation.)

If I want to export an object model for the DLL, I would use COM (and ATL -
or sometimes MFC - as helper framework/library).

If you don't use COM, you will start implementing custom memory management,
and other things, that COM already has defined and tested and very good
working. (So, no need to reinvent the wheel.)

However, assuming that you are using the same C++ compiler to build the DLL
and to build the DLL client, I think that you can export C++ classes with no
problems, if you do things right.

Giovanni




Re: exporting data from a dll - unresolved externals by Ben

Ben
Tue Jan 08 10:41:24 CST 2008


"2b|!2b==?" <user@domain.invalid> wrote in message
news:5umdnS5_I5NEPB7anZ2dnUVZ8qydnZ2d@bt.com...
>
>
> Ben Voigt [C++ MVP] wrote:
>
>> "2b|!2b==?" <user@domain.invalid> wrote in message
>> news:_9udncYmgLGlah_anZ2dnUVZ8uWdnZ2d@bt.com...
>>
>>>I have a DLL project that I need to export a data variable from. I have
>>>defined the variable in a .cpp file in the project like this
>>>
>>>//C++ file (DLL Project)
>>>
>>>class MYPROJ_API data_type
>>>{
>>> //Impl here ...
>>>};
>>>
>>>MYPROJ_API data_type exported_data;
>>>
>>>
>>>
>>>//header file (project that consumes DLL)
>>>extern MYPROJ_API data_type exported_data ;
>>
>>
>> It looks to me like the type is incomplete here, because the class
>> declaration isn't seen from the header file.
>>
>
> Not so. I kept the snippet simple for brevity sake. All other things like
> library paths, pre-processor defines etc are taken as assumed - (otherwise
> I will end up posting code for entire soln).

You said the class definition is in the implementation file. Therefore the
other project, having only the header file, doesn't see it.

If that is not accurate then rework your snippet to show where the class
definition is.

>
>>
>>>
>>>where MYPROJ_API is amacro that handles declspec import/export
>>
>>
>> dllexport of C++ classes is a bad idea. Optimally DLLs should only
>> export functions. You can pass around pointers to objects as long as
>> they are accessed through virtual functions (the client should only see
>> an interface definition with pure virtual functions and no data). Also
>> memory should always be freed in the same module that allocated it.
>>
>>
>
> Once again, your assumptions are wrong. I kept the code snnipet I posted
> here to a bare minimum for the previouslt stated reasons. the library is
> much more 'complicated' than I let on - what I pasted here was the bare
> bones that represented the salient features of the problem.

What assumptions are you referring to here?

>
> The DLL is a shared memory library - consequently, I cannot use any
> virtual functions - as vtable fptrs will be meaningless in another process
> space.

Separate your shared data from your code. The code pointers are valid
between the exe and dll, and should be kept out of the shared memory segment
itself.

You are using file mappings for shared memory, and not .SHARED sections,
correct?



Re: exporting data from a dll - unresolved externals by Alexander

Alexander
Wed Jan 09 12:22:59 CST 2008

That solves nothing since the class is still exported. What one
needs to do is define a C++ interface for the class and return
that from the C function (and the C++ interface should not
directly or indirectly reference any other C++ class that is not
in turn another C++ interface, should have no data nor static
members, and should not be derived from multiple other C++
interfaces). A C++ interface is a class containing only public
pure virtual methods. Also note you can't call operator delete
on the interface outside of your DLL, so you need to provide
another mechanism for disposing it (a global C function or
an interface emthod). Once you get there, you may realize
you've nearly reinvented COM, so you may go the extra step
and convert to a COM server...

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@mvps.org
MVP VC FAQ: http://vcfaq.mvps.org
=====================================

"Giovanni Dicanio" <giovanni.dicanio@invalid.com> wrote in message
news:uDZ60rdUIHA.3916@TK2MSFTNGP02.phx.gbl...
>
> "2b|!2b==?" <user@domain.invalid> ha scritto nel messaggio
> news:_9udncYmgLGlah_anZ2dnUVZ8uWdnZ2d@bt.com...
>>I have a DLL project that I need to export a data variable from. I have
>>defined the variable in a .cpp file in the project like this
>>
>> //C++ file (DLL Project)
>>
>> class MYPROJ_API data_type
>> {
>> //Impl here ...
>> };
>
> You are exporting a C++ class.
> Are you using the same compiler version to build the DLL and the client of
> your DLL?
>
>> MYPROJ_API data_type exported_data;
>
> Instead of exporting the class instance, you may try to export a global
> function which returns a pointer to the class instance, something like
> this:
>
> data_type globalData;
>
> MYPROJ_API data_type * GetExportedData(void)
> {
> return &globalData;
> }
>
> So the DLL client could call GetExportedData() to access the class
> instance.
>
> Giovanni
>
>



Re: exporting data from a dll - unresolved externals by Giovanni

Giovanni
Thu Jan 10 04:12:29 CST 2008

Yes, I know that.
In fact I also wrote in my previous post:

"If I want to export an object model for the DLL, I would use COM [...]"

IMHO, a pure Win32 DLL is fine if we expose a C interface (the
implementation can be C++, of course).
To export an object model from a DLL, COM is the way to go.

Giovanni



"Alexander Nickolov" <agnickolov@mvps.org> ha scritto nel messaggio
news:O$tQ4xuUIHA.4092@TK2MSFTNGP06.phx.gbl...
> That solves nothing since the class is still exported. What one
> needs to do is define a C++ interface for the class and return
> that from the C function (and the C++ interface should not
> directly or indirectly reference any other C++ class that is not
> in turn another C++ interface, should have no data nor static
> members, and should not be derived from multiple other C++
> interfaces). A C++ interface is a class containing only public
> pure virtual methods. Also note you can't call operator delete
> on the interface outside of your DLL, so you need to provide
> another mechanism for disposing it (a global C function or
> an interface emthod). Once you get there, you may realize
> you've nearly reinvented COM, so you may go the extra step
> and convert to a COM server...
>
> --
> =====================================
> Alexander Nickolov
> Microsoft MVP [VC], MCSD
> email: agnickolov@mvps.org
> MVP VC FAQ: http://vcfaq.mvps.org
> =====================================
>
> "Giovanni Dicanio" <giovanni.dicanio@invalid.com> wrote in message
> news:uDZ60rdUIHA.3916@TK2MSFTNGP02.phx.gbl...
>>
>> "2b|!2b==?" <user@domain.invalid> ha scritto nel messaggio
>> news:_9udncYmgLGlah_anZ2dnUVZ8uWdnZ2d@bt.com...
>>>I have a DLL project that I need to export a data variable from. I have
>>>defined the variable in a .cpp file in the project like this
>>>
>>> //C++ file (DLL Project)
>>>
>>> class MYPROJ_API data_type
>>> {
>>> //Impl here ...
>>> };
>>
>> You are exporting a C++ class.
>> Are you using the same compiler version to build the DLL and the client
>> of your DLL?
>>
>>> MYPROJ_API data_type exported_data;
>>
>> Instead of exporting the class instance, you may try to export a global
>> function which returns a pointer to the class instance, something like
>> this:
>>
>> data_type globalData;
>>
>> MYPROJ_API data_type * GetExportedData(void)
>> {
>> return &globalData;
>> }
>>
>> So the DLL client could call GetExportedData() to access the class
>> instance.
>>
>> Giovanni
>>
>>
>
>



Re: exporting data from a dll - unresolved externals by Alexander

Alexander
Thu Jan 10 18:29:16 CST 2008

I know you do :), but from your post it wasn't clear why you are
suggesting COM. My reply was a clarification for posterity.

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@mvps.org
MVP VC FAQ: http://vcfaq.mvps.org
=====================================

"Giovanni Dicanio" <giovanni.dicanio@invalid.com> wrote in message
news:u$y7OF3UIHA.4624@TK2MSFTNGP03.phx.gbl...
> Yes, I know that.
> In fact I also wrote in my previous post:
>
> "If I want to export an object model for the DLL, I would use COM [...]"
>
> IMHO, a pure Win32 DLL is fine if we expose a C interface (the
> implementation can be C++, of course).
> To export an object model from a DLL, COM is the way to go.
>
> Giovanni
>
>
>
> "Alexander Nickolov" <agnickolov@mvps.org> ha scritto nel messaggio
> news:O$tQ4xuUIHA.4092@TK2MSFTNGP06.phx.gbl...
>> That solves nothing since the class is still exported. What one
>> needs to do is define a C++ interface for the class and return
>> that from the C function (and the C++ interface should not
>> directly or indirectly reference any other C++ class that is not
>> in turn another C++ interface, should have no data nor static
>> members, and should not be derived from multiple other C++
>> interfaces). A C++ interface is a class containing only public
>> pure virtual methods. Also note you can't call operator delete
>> on the interface outside of your DLL, so you need to provide
>> another mechanism for disposing it (a global C function or
>> an interface emthod). Once you get there, you may realize
>> you've nearly reinvented COM, so you may go the extra step
>> and convert to a COM server...
>>
>> --
>> =====================================
>> Alexander Nickolov
>> Microsoft MVP [VC], MCSD
>> email: agnickolov@mvps.org
>> MVP VC FAQ: http://vcfaq.mvps.org
>> =====================================
>>
>> "Giovanni Dicanio" <giovanni.dicanio@invalid.com> wrote in message
>> news:uDZ60rdUIHA.3916@TK2MSFTNGP02.phx.gbl...
>>>
>>> "2b|!2b==?" <user@domain.invalid> ha scritto nel messaggio
>>> news:_9udncYmgLGlah_anZ2dnUVZ8uWdnZ2d@bt.com...
>>>>I have a DLL project that I need to export a data variable from. I have
>>>>defined the variable in a .cpp file in the project like this
>>>>
>>>> //C++ file (DLL Project)
>>>>
>>>> class MYPROJ_API data_type
>>>> {
>>>> //Impl here ...
>>>> };
>>>
>>> You are exporting a C++ class.
>>> Are you using the same compiler version to build the DLL and the client
>>> of your DLL?
>>>
>>>> MYPROJ_API data_type exported_data;
>>>
>>> Instead of exporting the class instance, you may try to export a global
>>> function which returns a pointer to the class instance, something like
>>> this:
>>>
>>> data_type globalData;
>>>
>>> MYPROJ_API data_type * GetExportedData(void)
>>> {
>>> return &globalData;
>>> }
>>>
>>> So the DLL client could call GetExportedData() to access the class
>>> instance.
>>>
>>> Giovanni
>>>
>>>
>>
>>
>
>