Solved

dllexport & dllimport

Posted on 2004-09-03
16
1,010 Views
Last Modified: 2013-11-20
I am getting link errors that I suspect have to do with dllimport/dllexport
(I am only slightly familiar with those terms)

I have an application (file "a.c") that creates an "a.out"; I am using Microsoft visual C++ 6.0

I have a file "b.c" (with header file "b.h") that creates a "b.dll" and a "b.lib". My "a.c" file references the functions in b.c, and I've updated my project settings to include the "b.lib"

Here are my link errors

DaqManager.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) int __cdecl getTemperature(struct TEMPERATURE *,int,float,float *)" (__imp_?getTemperature@@YAHPAUTEMPERATURE@@HMPAM@Z)


Here is the header file for "b.h"'

#ifndef TEMP_H
#define TEMP_H

  #ifdef WIN32
    #ifdef  DLL_EXPORT
      #define DLL_API __declspec(dllexport)
    #else
      #define DLL_API __declspec(dllimport)
    #endif
  #else
    #define DLL_API
  #endif

#endif

typedef struct {int    numOfChannels;
                int   *type;
                float **coeff;
               } TEMPERATURE;

DLL_API int    getTemperature(TEMPERATURE * tmp, int chan, float resistance, float * temp);











What do i need to do?            
0
Comment
Question by:happyloman
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
16 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 11978411
Declare your functions as

extern "C" DLL_API int    SomeFunc();

since that looks a bit like a name mangling problem.
0
 
LVL 7

Expert Comment

by:vijay_visana
ID: 11978989
try to put your exported function in def file
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 11979035
Add DLL_EXPORT constant to the list of precompiler constants in the project settings (see C++ tab, Precompiler). I don't know about WIN32 constant, usually Dll header looks like:

#ifdef  DLL_EXPORT                        // DL_EXPORT or some other unique constant is defined in the Dll project and not defined in the client project
  #define DLL_API __declspec(dllexport)   // in Dll project this is exported function
#else
  #define DLL_API __declspec(dllimport)   // in client project this is imported function
#endif

LNK2001 may appear sometimes if function implementation contains some typo, for example:

// h-file:
DLL_API int    getTemperature(TEMPERATURE * tmp, int chan, float resistance, float * temp);

// cpp-file:
int    get_Temperature(TEMPERATURE * tmp, int chan, float resistance, float * temp)
{
    ...
}

// some other place in cpp-file:
getTemperature(...);                      // this line causes LNK2001 error since getTemperature is declared but not implemented
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:happyloman
ID: 11996985
Guys,

Thanks for the suggestions... BUT..
here is the problem...

I CANNOT change anything in the b.lib, or the way it was created.
I have to use "b.lib" AS-IS!

The only thing I can change is my OWN project settings

Help!!??????
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 11997047
OK, you are writing client and not library.
In this case you must be sure that WIN32 precompiler constant is defined, and DLL_EXPORT constant is not defined. In this case getTemperature has dllimport attribute and should be taked brom b.lib.
Be sure that b.lib is added to the list of libraries for linker (Project - Settings - Link - Object/library modules).
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 11997067
"should be taken from b.lib"

I really need to read my post before clicking Submit, and not after this.
0
 

Author Comment

by:happyloman
ID: 11997577
AlexFM

Yes, I'm familiar with adding link libraries ("something.lib") in Microsoft Visual C++ via "Project/settings/Link/Category: input/Object/library modules" and then also adding in the correct "additional library path"

I've done that before with other libs.

BUT, I still get the same unresolved external symbol.

Is there a way for me to "inspect" the library ("b.lib") to verify that it is built correctly?

For example, if you are familiar with JAVA...

I once found out that a "something.jar" file was corrupted, after I inspected it through "jar tvf something.jar".... My client code, which depended on the jar file, was unable to run, because of it.  

THANKS for help!!!!!!!!
0
 

Author Comment

by:happyloman
ID: 11997608
By the way, there is also a "b.dll" in addition to the "b.lib" (don't know if that is an important detail to you or not"

I've also cut-pasted the Makefile which was used to build the "b.lib" below.
(Although I was unable to use this makefile to build)

#Makefile.msc

OBJS = temp.obj
MISCFLAGS = /D "WIN32"

temp.lib : $(OBJS)
      cl  /Fetemp.dll /LD /GD $(OBJS)

dr.exe   : dr.obj temp.lib
      cl  dr.obj temp.lib

dr.obj   : dr.c
      cl /c  $(MISCFLAGS) dr.c

temp.obj   : temp.c
      cl /c $(MISCFLAGS)  temp.c

clean :
      del *.exe
      del *.obj
      del *.lib
      del *.dll
      del *.exp

0
 

Author Comment

by:happyloman
ID: 11997792
AlexFM,

You wrote

"OK, you are writing client and not library.
In this case you must be sure that WIN32 precompiler constant is defined, and DLL_EXPORT constant is not defined."

I just looked at the "temp.c" code (the library code) and it has

#define  DLL_EXPORT

Is that wrong?

(By the way, I already have the WIN32 precompiler constant defined, under
prject settings, c/c++/ Preprocessor defintions"

THNKS!!!
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 11998404
This is right for the library code. This means, when library is built, function is defined as dllexport. Client project should not contain this constant, and function is defined as dllimport. I hope that line
#define  DLL_EXPORT
is before line
#include "b.h"
in temp.c file.

I don't know how to see list of files exported files lib, but you can do this with Dll. Use dumpbin utility or Depends (Dependancy Walker)  program. dumpbin is command-line utility which comes with VC++. Depends is GUI program listed in the Programs, Microsoft Visual Studio, Tools menu. On my computer it can be found in
C:\Program Files\Microsoft Visual Studio\Common\Tools\DEPENDS.EXE
0
 

Author Comment

by:happyloman
ID: 11998517
AlexFM,

Yes, I've just checked.

--------------------------------------------------------
1. the DLL EXPORT is before "include b.h" in "temp.c".. it is like this...

#define  DLL_EXPORT
#include "temp.h"

---------------------------------------------------------
2. I ran dumpbin on b.dll:

$ dumpbin temp.dll
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file temp.dll

File Type: DLL

  Summary

        5000 .data
        1000 .rdata
        1000 .reloc
        B000 .text

---------------------------------------------------------------------
3. I ran dumpbin on b.lib


$ dumpbin temp.lib
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file temp.lib

File Type: LIBRARY

  Summary

          BD .debug$S
          14 .idata$2
          14 .idata$3
           4 .idata$4
           4 .idata$5
           A .idata$6



I ran Depends.exe on the b.dll, it shows me the three unresolved symbols

0
 
LVL 48

Expert Comment

by:AlexFM
ID: 11998602
I am confused with b.dll and temp.dll. Are you working with two libraries?
To see list of exported symbols use:
DUMPBIN /EXPORTS DLL_file_name

>>I ran Depends.exe on the b.dll, it shows me the three unresolved symbols.

It cannot be unresolved symbols. Possibly these are exported functions. Dll cannot be built if it contains unresolved symbols.
0
 

Author Comment

by:happyloman
ID: 11998667
AlexFM

I just aliased b.dll for temp.dll (Trying to simplify the problem)

In my posts here, I am just CALLING temp.dll as b.dll, and temp.lib as b.lib.

I will try your suggestions right now
0
 

Author Comment

by:happyloman
ID: 11998678
$ dumpbin /exports temp.lib
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file temp.lib

File Type: LIBRARY

     Exports

       ordinal    name

                  _freeTemp
                  _getTemperature
                  _initTempPtr

  Summary

          BD .debug$S
          14 .idata$2
          14 .idata$3
           4 .idata$4
           4 .idata$5
           A .idata$6
0
 
LVL 57

Expert Comment

by:Julian Hansen
ID: 11998751
I am a bit confused. You say the b.lib was created from b.c which compiles to a .DLL in which case the .lib should handle the thunking from the call in your a.c file to the name mangled version in the DLL. However, it appears that this is not the case so drastic measures are called for.

Here is what you do.

You are using MSVC 6.0 so you should have a copy of Depends on hand.
Use this to look inside the DLL for how the function is named internally.
Next abandon the dllimport stuff and use good old LoadLibrary and GetProcAddress

So
typedef int (*FUNC_TYPE)(TEMPERATURE, ... etc );

HMODULE hMod = LoadLibrary ( "b.dll" ) ;
FUNC_TYPE pProc = (FUNC_TYPE)GetProcAddress (hMod, "?fnAdll@@YAHPAUTEMP@@HMPAM@Z" );
pProc (...).

FreeLibrary ( hMod ) ;

That should work


0
 

Author Comment

by:happyloman
ID: 11998769
Clarification on what I wrote earlier

I wrote
>>I ran Depends.exe on the b.dll, it shows me the three unresolved symbols.

You wrote
It cannot be unresolved symbols. Possibly these are exported functions. Dll cannot be built if it contains unresolved symbols.

What I mean is that, when I ran Depends.exe on the b.dll (temp.dll), I saw
the three symbols listed in the "ordinal/hint/function/entry point" table
Like this... (unfortunately I can't give you a screen dump)
1. (ox0000) freeTemp          
2. (0x0001) getTemperature
3. (0x0002) initTempPtr

AND, to refresh your memory, here are my link errors..


DaqManager.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) struct TEMPERATURE * __cdecl initTempPtr(void)" (__imp_?initTempPtr@@YAPAUTEMPERATURE@@XZ)

DaqManager.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) void __cdecl freeTemp(struct TEMPERATURE *)" (__imp_?freeTemp@@YAXPAUTEMPERATURE@@@Z)

DaqManager.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) int __cdecl getTemperature(struct TEMPERATURE *,int,float,float *)" (__imp_?getTemperature@@YAHPAUTEMPERATURE@@HMPAM@Z)








0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Whole sheet autoscrub still needed 19 55
move a line in eclipse 3 112
Detect file exist or not 3 215
ERP and the other system process verification 5 26
This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

710 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question