1
votes

I have two existing executables A and T, in the same solution that both ran just fine before I touched them. In executable A is a header defining a class P, and a prototype for a static instance MyP. The definitions are compiled in project A. In executable T, I wanted to call member functions of MyP in project A, so I added dllimport/export macros to the declarations of the class and MyP in the headers (not at the definitions), and included the headers in project T. The dllimport/export macros are standard, and A_EXPORTS is defined in project A, but not in T.

#ifdef A_EXPORTS
#define A_API __declspec(dllexport)
#else
#define A_API __declspec(dllimport)
#endif

//various definitions and includes, defining ENUM_RECORDING_TYPE and ERROR
A_API HFILE viosopen(const _TCHAR *path, ENUM_RECORDING_TYPE rt, int flags);
A_API struct P { 
    ERROR B(SHORT phraseNum);
};
A_API extern P MyP;

I added project A as a dependency on project T in the solution. A still compiles fine, but T comes up with unresolved external symbol "__declspec(import) <snip> referenced in function <snip> for the function calls, and unresolved external symbol "__declspec(dllimport) class P MyP" <snip> for the static object. I also see in the output log, right after it starts linking: Creating library Debug/A.lib and object Debug/A.exp which seems ominous since it's supposed to be linking against the existing executable.

My question is: how can I tell MSVC 2010 where those are? I thought simply setting A as a dependency would have it figure that out automatically. I can link against the existing executable, right?

2
you need to show us your declarations in project A. I'm suspecting that you didn't flag the class and the static instance correctly (using A_API)YeenFei
Are you trying to statically link to the implementation of MyP etc. or are you trying to dynamically link to A.exe?Frank Boyne
@Frank Boyne: Since exe and dll are basically the same file format, I figured it could link as if it were a dll, so dynamic. Static would be better, since I only need four functions, but I don't want to add another project to make a static lib version of A.Mooing Duck
@YeehFei: I copied in the code (with the renamed names).Mooing Duck

2 Answers

2
votes

To statically link your program you don't need the __declspec() stuff and you don't need a separate project to create a LIB file. I think you can just link using the .obj file from your A project.

Your A project has a header file and presumably has a .cpp file that contains the implementation of the items described in that header. Let's say your header file is foo.h and the associated implementation is foo.cpp. When compiled, there should be a foo.obj intermediate file in the <solutiondir>\A\Debug or <solutiondir>\A\release intermediate folder. That file can be used by the linker.

In project T's properties, find Linker | Input and change the "Additional Dependencies" property to include the foo.obj file. One approach would be to use a relative file path to locate the file - for example ..\A\Debug\foo.obj in your debug configuration. Another approach is to use the simple file name in "Additional Dependencies" - foo.obj - and then use Linker | General | Additional Library Directories" to help the linker find the file - e.g., ..\A\$(IntDir). Using the $(IntDir) macro has the advantage that the same value works for Debug and Release settings.

Remember to set up a build dependency from your T project to your A project to be sure the A project is compiled first. Otherwise the foo.obj file might not exist when the T linker comes to look for it. In the Solution properties, select Project Dependencies and then set Project T depends on Project A.

To dynamically link you need to use the A.LIB file as @ajay said. The __declspec(DllImport) tells the compiler what functions and data you are importing but doesn't tell it where you are importing those things from.

Using the A.LIB file as input to the linker is much the same as using the foo.obj file in the statically linking case except that the lib file ends up in the solution output directory <solutiondir>\Debug instead of the project intermediate directory <solutiondir>\A\Debug.

This walkthrough on creating and using a DLL might be useful background.

0
votes

I asssume project A is DLL not an EXE, which is successfully producing a LIB file. You need to use the A.LIB as Linker Input in project B. Just producing LIB file wont make other projects automatically link to it.