Click to See Complete Forum and Search --> : DLL troubles


Eric Smith
October 14th, 1999, 06:26 PM
Hello all.

I am new to writing DLLs, but I find myself with a candidate for a DLL with my current project.

It is written in C++ and basically consists of one object consisting of sister objects. No problem there. In fact, the DLL compiles nicely with only a minor complaint about CString needing a DLL interface.

My real problem comes in when I try to write a program that will use the DLL. I get a list of unresolved external symbols for my exported functions. I thought the functions needed the extern "C" directive, but that doesn't seem to fix anything.

Here is a clip of the extern "C" definition. The file is a .cpp. It compiles, but the linker generates decorated names anyway. I will also post a partial list of the DUMPBIN /externs and the unresolved list.

------DUMPBIN output -------
0 characteristics
38061B52 time date stamp Thu Oct 14 11:05:06 1999
0.00 version
1 ordinal base
129 number of functions
129 number of names

ordinal hint RVA name
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
93 5C 00001172 ?Collect@CBIOSInfo@@QAE_NXZ
94 5D 00001177 ?Collect@CCPUInfo@@QAE_NXZ
95 5E 000010EB ?Collect@CCdRomInfo@@QAE_NAAVCStringArray@@@Z
96 5F 000011AE ?Collect@CDirectXInfo@@QAE_NXZ
97 60 000011EF ?Collect@CDisplayInfo@@QAE_NAAVCStringArray@@@Z
98 61 00001014 ?Collect@CDriveInfo@@QAE_NAAVCStringArray@@@Z
99 62 0000114F ?Collect@CGlideInfo@@QAE_NXZ
100 63 0000111D ?Collect@CModemInfo@@QAE_NAAVCStringArray@@@Z
101 64 000011CC ?Collect@CMonitorInfo@@QAE_NAAVCStringArray@@@Z
102 65 000011FE ?Collect@CNetInfo@@QAE_NAAVCStringArray@@@Z
103 66 00001087 ?Collect@COSInfo@@QAE_NXZ
104 67 000010E6 ?Collect@COpenGLInfo@@QAE_NXZ
105 68 000012A8 ?Collect@CPortInfo@@QAE_NAAVCStringArray@@@Z
106 69 000010FF ?Collect@CSCSIInfo@@QAE_NXZ
107 6A 00001118 ?Collect@CSoundInfo@@QAE_NAAVCStringArray@@@Z


-------------------------------------------------------
----- code header ----------

extern "C" {
class DLLAPI CSystem
{
public:
bool Collect_OpenGLInfo();
COpenGLInfo m_OpenGLInfo;
bool Collect_GlideInfo();
CGlideInfo m_GlideInfo;
CCPUInfo m_CPUInfo;
bool Collect_DirectXInfo();
CDirectXInfo m_DirectXInfo;
CDriveInfo m_DriveInfo;
CBIOSInfo m_BIOSInfo;
bool Collect_BIOSInfo();
bool Collect_PortInfo();
CPortInfo m_PortInfo;
bool Collect_SoundInfo();
CSoundInfo m_SoundInfo;
CNetInfo m_NetInfo;
bool Collect_NetInfo();
bool Collect_CDRomInfo();
CCdRomInfo m_CDRomInfo;
CMonitorInfo m_MonitorInfo;
bool Collect_MonitorInfo();
CDisplayInfo m_DisplayInfo;
bool m_OS_Grabbed;
bool Collect_DisplayInfo();
COSInfo m_OSInfo;
CStringArray RegKeys;
bool EnumReg();
bool Collect_CPUInfo();
bool Collect_OSInfo();
bool Collect_MemoryInfo();
bool Collect_DriveInfo();
long m_MemFree;
long m_MemTotal;
CSystem();



------------------------------------------
-----Error output---------------

SIP.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: bool __thiscall CSystem::Collect_OpenGLInfo(void)" (__imp_?Collect_OpenGLInfo@CSystem@@QAE_NXZ)
SIP.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: bool __thiscall CSystem::Collect_GlideInfo(void)" (__imp_?Collect_GlideInfo@CSystem@@QAE_NXZ)
SIP.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: bool __thiscall CSystem::Collect_DirectXInfo(void)" (__imp_?Collect_DirectXInfo@CSystem@@QAE_NXZ)
SIP.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: bool __thiscall CSystem::Collect_DriveInfo(void)" (__imp_?Collect_DriveInfo@CSystem@@QAE_NXZ)
SIP.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: bool __thiscall CSystem::Collect_BIOSInfo(void)" (__imp_?Collect_BIOSInfo@CSystem@@QAE_NXZ)

Thanks for any help that anyone can bestow upon me.

October 14th, 1999, 08:30 PM
You need to export classes/functions in your dll.
Try to do the following:

Add the following lines into the .h file:

#ifdef _MYDLL
#define ImpExpDecl __declspec (dllexport)
#else
#define ImpExpDecl __declspec (dllimport)
#endif

class ImpExpDecl CSystem
{
...
}

Then do not forget to add _MYDLL to the list of the preprocessor definitions of your DLL project (together with WIN32,_WINDOWS, etc.) (see C/C++ tab, category Preprocessor in your DLL project settings)

Eric Smith
October 15th, 1999, 10:51 AM
Thanks, but that is what the DLLAPI is in my header file.


extern "C" {
class DLLAPI CSystem
{
public:
bool Collect_OpenGLInfo();
COpenGLInfo m_OpenGLInfo;
bool Collect_GlideInfo();




The decorated versions of the functions export just fine. The fact that they are decorated makes them impossible to use.

ALM
October 25th, 1999, 06:03 PM
The extern "C" declaration is used to tell the C++ compiler not to add the name decorations at the end of GLOBAL functions. The purpose of it is so that C-compatible code (such as C, VB, Delphi, etc.) can call these functions.

C++ classes which you export from a DLL are meant to be used by C++ source code in other applications. So you include the header in your program and instanciate the class as if it were part of the same project:

CSystem mySystemObjectImportedFromDLL;
mySystemObjectImportedFromDLL.Whatever(...);



So what you need to do is: remove the extern "C" from the class, rebuild the DLL, include the header file in the other project, and then use the class as usual.

Cheers!
Alvaro