shieldfoss
shieldfoss

Reputation: 884

How do I get started writing DLLs in visual C++?

As the title says, although I guess what I really mean is "And using them later."

The Setup

I have followed this answer:

https://stackoverflow.com/a/13219631/696407

which creates a very simple dll

#include <stdio.h>
extern "C"
{
    __declspec(dllexport) void DisplayHelloFromMyDLL()
    {
        printf ("Hello DLL.\n");
    }
}

and I now have a dll compiled for release:

When I run DllTest.dll through dumpbin, I find this line:

1    0 00001000 DisplayHelloFromMyDLL = _DisplayHelloFromMyDLL

USING THE DLL

To use that function in a new solution, I believe I must

  1. Start a project in a new solution
  2. Add the location of the DLL to the project under
    • Properties
      • Configuration Properties
        • Linker
          • General
            • Additional Library Directories
  3. Add the .lib file under
    • Properties
      • Configuration Properties
        • Linker
          • Input
            • Additional Dependencies

and, having added the .lib there, the next step is... hvæt?

My code right now:

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    while(1)
    {
        DisplayHelloFromMyDLL();
    }
    return 0;
}

but that doesn't work.

EDIT: I guess "doesn't work" is vague. The function gets Error: identifier "DisplayHelloFromMyDLL" is undefined

(Side question: Is my function called DisplayHelloFromMyDLL(); or _DisplayHelloFromMyDLL();?)

Upvotes: 1

Views: 278

Answers (2)

Dialecticus
Dialecticus

Reputation: 16761

You need .h for compiler (use with #include, and add the folder to .h file as relative path to Configuration Properties > C/C++ > General > Additional Include Directories). Aside from .lib for linker you also need .dll to actually run the test application.

EDIT: There are two types of DLL's that you can make. First are C-like DLL's, with functions that have signatures as if they are written in C instead of in C++. All Windows DLL's (user32.dll, shell32.dll, version.dll) are built as such. The other are C++ DLL's, with functions that are part of the class. MFC and Standard C++ Libraries are such.

If you want to make a C++ DLL then you have to declare all classes that are part of interface as __declspec(dllexport) in your DLL project and __declspec(dllimport) in all projects that would use DLL. Usually the same file is used for this, but with a macro that is defined accordingly to one or the other. If you create a DLL from Visual Studio project template you would see this code.

Your case is actually the simpler case, as you want C-like DLL. You don't have to fiddle with this __declspec rubbish, but you need one additional .def file in DLL project. This should be the content of the .def file:

LIBRARY MyApi

EXPORTS
    DisplayHelloFromMyDLL

Your header file (.h file) should look like this:

#pragma once

#ifndef HELLO_DLL_INCLUDED
#define HELLO_DLL_INCLUDED

#ifdef __cplusplus
extern "C" {
#endif

void DisplayHelloFromMyDLL();

#ifdef __cplusplus
};
#endif

#endif // HELLO_DLL_INCLUDED

__declspec(dllimport) tells the compiler that this function (or class) is defined somewhere else, and that linker will find it and link it. __declspec(dllexport) tells the compiler (and linker) that this function (or class) should be exported and be part of DLL interface. If class has neither of those then it's just a class that should be defined in the same project.

Upvotes: 2

Sean
Sean

Reputation: 62472

To consume your .dll you need two things, a header file and a .lib.

The header file is so that the compiler knows there is a function somewhere with the name DisplayHelloFromMyDLL(). At this point it doesn't matter where it is, just that you've told the compiler it's somewhere. The linker will take care of the where bit.

The .lib file is for the linker. It tells the linker that DisplayHelloFromMyDLL() lives in a .dll, and that (in your case) the name of the dll is DllTest.dll. When your program starts up the Windows loader will use this information to load the .dll into your process and will perform any address fixups to make sure that calling DisplayHelloFromMyDLL() in your application calls the function in your .dll.

You don't actually need the .dll in order to build your executable, only to run it.

Upvotes: 0

Related Questions