Archived

This topic is now archived and is closed to further replies.

SpreeTree

Exporting variables from a dll issue

Recommended Posts

I am having trouble exporting a vaiable from my dll. I have looked at the vc6 sample code, and I am doing (as far as I can see) nothing wrong. Heres the code from the .h file (well a couple stuck together )

#ifdef TEST_EXPORTS
#define MEXPORT	 __declspec(dllimport)
#else
#define MEXPORT  __declspec(dllexport)
#endif

extern MEXPORT int* randomPointer;
extern MEXPORT void RandomFunction(int _int);



and in my cpp file...

   

MEXPORT int* randomPointer = NULL
MEXPORT void RandomFunction(int _int)
{
}

Now when i come to use these in my application, the function is fine. The compiler can find it, and use it. Same goes for all the class definitions too. But when i try to use the variable I get an undefined symbol linker error. I can remove that error by defining the variable _again_ in theapplication, bu tthis then means I have teo copies of the same variable flying about. I am using name spaces, but U have made sure, and the name spacing is correct, so I can count that out. Does anyone have any idea of what the problem might be and how to fix if? Thanks in advance Spree [Edit] On a side note, what exactly is the reason behind __declspec(dllimport)? I enable that, and all hell breaks lose! [edited by - SpreeTree on May 18, 2004 7:20:45 PM]

Share this post


Link to post
Share on other sites
Did you link your exe''s project against the .lib file produced by building the DLL project?

Share this post


Link to post
Share on other sites
quote:
Original post by SiCrane
Did you link your exe''s project against the .lib file produced by building the DLL project?


Yes, the lib is linked to. I removed it to see what happened, and all the other exported symbols came up as unresoved external symbols. I put it back, and again, just the variable is having trouble

Spree

Share this post


Link to post
Share on other sites
quote:
Original post by fyhuang
Isn''t your import/export macro reversed?


Yes its reversed, dont ask me why :s
But dllexport is being used, not dllimport

Spree

Share this post


Link to post
Share on other sites
The DLL:

DLL.h

#ifdef __DLL_EXPORTS__
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif

#include <windows.h>

extern "C" DLLAPI int iDllVar;
extern "C" DLLAPI void dllTest(void);


DLL.cpp
   
#ifndef __DLL_EXPORTS__
#define __DLL_EXPORTS__
#endif

#include "DLL.h"

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}

return TRUE;
}

DLLAPI void dllTest(void)
{
MessageBox(NULL, "dllTest()", "dllTest()", MB_OK);
}


The Program:

main.h
   
#ifndef __MAIN_H__
#define __MAIN_H__

#pragma comment(lib, "DLL.lib")

#include "Optimize.h"
#include "DLL.h"

#endif


main.cpp
   
#include "main.h"

int main(int argc, char *argv[])
{
iDllVar = 0;
dllTest();
return 0;
}


I'm pretty sure thats right

[edited by - Smacker_626 on May 18, 2004 7:43:27 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Smacker_626

I''m pretty sure thats right

[edited by - Smacker_626 on May 18, 2004 7:43:27 PM]


You havnt show in your code how you define the variable iDllVar? I added the "C" extern to the extern declaration, but still the same problem occured

Spree

Share this post


Link to post
Share on other sites

#ifdef __DLL_EXPORTS__
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif

#ifndef __DLL_H__
#define __DLL_H__

#define WIN32_LEAN_AND_MEAN

#include <windows.h>

DLLAPI int iDllVar;
DLLAPI void dllTest(void);

#else /* __DLL_H__ */

extern "C" DLLAPI int iDllVar;
extern "C" DLLAPI void dllTest(void);

#endif /* __DLL_H__ */


sorry

EDIT: I hate the source tag

[edited by - Smacker_626 on May 18, 2004 8:09:27 PM]

Share this post


Link to post
Share on other sites
No, I am still getting the same unresolved symbol message.

I have even created an app which uses the dll created from the vc6 "A dll that exports some symbols", and even that application is gettong an unresolved symbol for the variables, but not the classes or functions.

The application I am using is a win32 console application started with void main(void). I can''t imagine this causeing any problems?

Spree

Share this post


Link to post
Share on other sites
Ok, heres the source from a little test app that does exactly the same thing

dllmain.h

#include <windows.h>

#define MDLLEXPORTS
#ifdef MDLLEXPORTS
#define MEXPORT __declspec(dllexport)
#else
#define MEXPORT __declspec(dllimport)
#endif

// Create a class to export

class MEXPORT CTestClass
{
public:
CTestClass(void) {}
~CTestClass(void) {}
};

extern MEXPORT void randomFunction(int _int);
extern MEXPORT int* randomPointer;


dllmain.cpp

#include "dllmain.h"

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// Put any init code here

case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
// Put any shutdown code here

break;
}
return TRUE;
}

MEXPORT void randomFunction(int _int)
{
}
MEXPORT int* randomPointer = NULL;


And my console app (no .h file here)


#include <windows.h>
#include "dllmain.h"

#pragma comment(lib, "test2.lib")

void main(void)
{
CTestClass testClass;
randomPointer = NULL;
randomFunction(1);
}


The dll and lib are created fine (the dll is called test2.dll). When building the console app, i get:


Linking...
Creating library Debug/consoleApp.lib and object Debug/consoleApp.exp
consoleMain.obj : error LNK2001: unresolved external symbol "int * randomPointer" (?randomPointer@@3PAHA)
Debug/consoleApp.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.


The .plg file (for the dll) is:

 
Build Log

--------------------Configuration: Test2 - Win32 Debug--------------------

Command Lines
Creating temporary file "C:\DOCUME~1\LEEWIN~1\LOCALS~1\Temp\RSP3F.tmp" with contents
[
/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST2_EXPORTS" /Fp"Debug/Test2.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"C:\Test2\dllmain.cpp"
]
Creating command line "cl.exe @C:\DOCUME~1\LEEWIN~1\LOCALS~1\Temp\RSP3F.tmp"
Creating temporary file "C:\DOCUME~1\LEEWIN~1\LOCALS~1\Temp\RSP40.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /pdb:"Debug/Test2.pdb" /debug /machine:I386 /out:"Debug/Test2.dll" /implib:"Debug/Test2.lib" /pdbtype:sept
.\Debug\dllmain.obj
]
Creating command line "link.exe @C:\DOCUME~1\LEEWIN~1\LOCALS~1\Temp\RSP40.tmp"
Output Window
Compiling...
dllmain.cpp
Linking...
Creating library Debug/Test2.lib and object Debug/Test2.exp



Results
Test2.dll - 0 error(s), 0 warning(s)



and the plg file for the console app is

Build Log

--------------------Configuration: consoleApp - Win32 Debug--------------------

Command Lines
Creating temporary file "C:\DOCUME~1\LEEWIN~1\LOCALS~1\Temp\RSP47.tmp" with contents
[
/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"Debug/consoleApp.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"C:\Test2\consoleMain.cpp"
]
Creating command line "cl.exe @C:\DOCUME~1\LEEWIN~1\LOCALS~1\Temp\RSP47.tmp"
Creating temporary file "C:\DOCUME~1\LEEWIN~1\LOCALS~1\Temp\RSP48.tmp" with contents
[
test2.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/consoleApp.pdb" /debug /machine:I386 /out:"Debug/consoleApp.exe" /pdbtype:sept /libpath:"c:\test2\debug"
.\Debug\consoleMain.obj
]
Creating command line "link.exe @C:\DOCUME~1\LEEWIN~1\LOCALS~1\Temp\RSP48.tmp"
Output Window
Compiling...
consoleMain.cpp
Linking...
Creating library Debug/consoleApp.lib and object Debug/consoleApp.exp
consoleMain.obj : error LNK2001: unresolved external symbol "int * randomPointer" (?randomPointer@@3PAHA)
Debug/consoleApp.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.



Results
consoleApp.exe - 2 error(s), 0 warning(s)



Hop you can see a problem in there

Thanks
Spree

[edited by - SpreeTree on May 19, 2004 4:35:24 AM]

Share this post


Link to post
Share on other sites
As an aside. I created a brand new .net 2002 project, followed the exact same steps as i did when I created the vc6 dll and console project, and in this case, the variable was exported correctly, and no linking errors occured.

But, i also got .net to convert the vc6 project I am having trouble with, and when that was compiled in .net, I _did_ get the linking error on the variable.

The linking error only seems to occur when I try to access variable exported by a vc6 dll. Even when i use a vc6 console app with a .net2002 compiled dll, the variables have been exported fine.

I acn only assume that this means there is something wrong with my vc6 dll project settings somewhere?

Spree

[edited by - SpreeTree on May 19, 2004 5:14:54 AM]

Share this post


Link to post
Share on other sites
First off when you create a DLL project in VC++ it defines PROJECTNAME_EXPORTS for you, so if I created a new DLL project named dll it would define DLL_EXPORTS for me.

If you look at the dll's .plg file VC++ has defined TEST2_EXPORTS for you.

In dllmain.h you have
#define MDLLEXPORTS
so when that header is included MEXPORT is always defined as __declspec(dllexport)

take #define MDLLEXPORTS out and change
#ifdef MDLLEXPORTS
to
#ifdef TEST2_EXPORTS

hope that fix's it

EDIT:
if you want you can just add something like this to the .cpp file with DllMain in it (this has to be before you include the .h file):

#ifndef DLL_EXPORTS
#define DLL_EXPORTS
#endif

and use something like this in the DLL's .h file:

#ifdef DLL_EXPORTS
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif

[edited by - Smacker_626 on May 19, 2004 11:02:01 PM]

Share this post


Link to post
Share on other sites
BTW, if you have .NET 2K2 why don't you use it?

And if your going to use LoadLibrary() and GetProcAddress() to use the functions in your DLL you should use extern "C" so the names aren't changed

[edited by - Smacker_626 on May 19, 2004 11:07:36 PM]

Share this post


Link to post
Share on other sites
Your right that did fix it. I errr... (slightly embarrassed), undefined the define to set up __declspec(dllimport), in another file earlier to test something and err.. never took it out :s

Everyone laugh at the daft programmer...

Hopefully wont be using LoadLibrary() and GetProcAddress(), but I will bear that in mind.

As for why I dont use 2002? I have yet to move onto forms, and have you ever tried to use 2002 and MFC? VC6 is a mucch better interface for MFC programming IMO

Thanks for all your help
Spree

Share this post


Link to post
Share on other sites
Glad I could help

I only have MSVS 6.0, and I don't know much about the MFC library, if I ever need a GUI i'll just use FLTK :D

I would like to get VS .NET but I just spent ~$700 upgrading my PC again so i'm broke lol

[edited by - Smacker_626 on May 20, 2004 4:11:01 AM]

Share this post


Link to post
Share on other sites