Dynamic link library does not generate a .lib file when compiled (Visual Studio C++ Express)
Asked Answered
M

1

33

As part of learning C++, I wrote a simple class library + application that references it. Everything builds, except the class library does not generate a .lib file, which results in the application throwing a "LINK : fatal error LNK1104: cannot open file". This seems very reasonable; obviously, if a necessary file isn't there, there's an error and it's fatal. (Side note: I don't have a book yet)

So, I went looking for reasons a .lib file might not be generated. My search-fu, by the way, is rather weak. All I did find was that, if the library did not have any __declspec(dllexport) tags, it would not export a .lib.

I shall now post the header and .cpp contents of the class library (A simple "Console" class with one "Write(std::string)" method).

Header:

// Extensions.h

#pragma once

#include "stdafx.h"

namespace Extensions {

    __declspec(dllexport) class Console
    {
    public:
        __declspec(dllexport) static void Write(std::string text);
    };
}

I am unsure whether I need to tag the function when I've tagged the class, but I can check that when it works.

And the .cpp file:

// This is the main DLL file.

#include "stdafx.h"

// #include "Console.h"

namespace Extensions {

    void Console::Write(std::string text)
    {
        std::cout << text.c_str();
    }
}

I've checked and it is set to generate a dynamic link library.

Thanks.

Muliebrity answered 16/2, 2011 at 17:25 Comment(2)
Why is // #include "Console.h" commented out? How can that compile?Prepossess
It's #include'd in "stdafx.h". Specifically including it in "Console.cpp" results in a "defined twice" error.Muliebrity
M
24

Here is some sample code that demonstrates how to correctly export a class. Pay attention to the CONSOLETEST_EXPORT macro. This is the missing part of your solution. You need to define this macro in your DLL project, and leave it undefined in the projects that reference this dll.

// MAIN.CPP - TestApplication

#include <iostream>
#include "ConsoleTest.h"

int main(int argc, char** argv)
{
    std::cout << "Hello World" << std::endl;

    ConsoleTest test;

    test.Write();
    ConsoleTest::StaticWrite();

    system("pause");
}


// ConsoleTest.h - TestDll 

#include <iostream>

#ifdef CONSOLETEST_EXPORT
    #define CONSOLETEST_API __declspec(dllexport)
#else
    #define CONSOLETEST_API __declspec(dllimport)
#endif

class CONSOLETEST_API ConsoleTest
{
public:
    ConsoleTest();
    ~ConsoleTest();
    void Write();
    static void StaticWrite();
};


// ConsoleTest.cpp - TestDll

#include "ConsoleTest.h"

ConsoleTest::ConsoleTest()
{
}

ConsoleTest::~ConsoleTest()
{
}

void ConsoleTest::Write()
{
    std::cout << "Instance Write" << std::endl;
}

void ConsoleTest::StaticWrite()
{
    std::cout << "Static Write" << std::endl;
}

Check out this article on codeproject for more details. HowTo: Export C++ classes from a DLL

Montage answered 16/2, 2011 at 18:54 Comment(12)
Sorry for the lousy formatting of the code. There are three separate code files in that block, main.cpp, ConsoleTest.h and ConsoleTest.cpp.Montage
Much better. The application is now complaining that Console doesn't exist (I changed the name back to Console from ConsoleTest, because I'm a bit CDO). The application includes "Console.h" fine and, aside from the name change and including "stdafx.h" (VSE complained if I left it out) I'm using your code exactly. Do I continue this question or start a new one?Muliebrity
No problem. Parsing into separate files seemed to be pretty easy.Muliebrity
Are you getting a compile error or a link error? And did you define CONSOLETEST_EXPORT in the project settings of your dll project?Montage
...In that case, I'm not sure where to #define it. I was just defining it in the header file, which, now that I think about it, probably wasn't that smart. And the first error is "error C2065: 'Console' : undeclared identifier"Muliebrity
Right click on your dll project in the Solution Explorer and choose 'Properties'. Under Configuration Properties->C/C++->Preprocessor you'll find the field 'Preprocessor Definitions'. Add it to the end of this list. Make sure to set it for both debug and release builds.Montage
Exact same first error, even though Console.h clearly considers it defined.Muliebrity
Have you added include paths for your headers and libraries to your main project? The compiler needs to know where to find your header and library files. Properties->Configuration Properties->C/C++->General 'Additional Include Directores Properties->Configuration Properties->Linker->General 'Additional Library Directories' Properties->Configuration Properties->Linker->Input 'Additional Dependencies'Montage
I stuck the location of the .dll and .lib files in each; I also stuck the location of the .h files in each. Terminated each with a semicolon. And...It's the same error. "error C2065: 'Console' : undeclared identifier"Muliebrity
Ok, that's new. I commented out the Console code in the application and rebuilt it to try something else without removing the reference and I got "LINK : fatal error LNK1104: cannot open file 'C:...\Projects\CPlusPlus\Extensions\Extensions2.obj'" It's looking in the wrong directory for that - I added the right directory to the linkages, but no go.Muliebrity
I think you're going to need to find someone who can sit down beside you to debug these errors. I suggest you create a new solution with the two projects I used above, and get that working first. That should help you learn how to configure the Visual Studio environment to correctly build your projects.Montage
Thanks for the information about needing to add the __declspec macro! This is an old comment thread, but I wanted to add: One thing I figured I should mention is that, if you're creating a DLL in Visual Studio (2013 if it matters), VS will automatically add a definition for PROJECTNAME_EXPORTS under Properties > C/C++ > Preprocessor > Preprocessor Definitions. So, in this case, you should change the beginning macro to #ifdef CONSOLETEST_EXPORTS (notice the 'S' on "EXPORTS").Fay

© 2022 - 2024 — McMap. All rights reserved.