How to export C++ class as a dll?

Alwyn picture Alwyn · May 21, 2013 · Viewed 13.2k times · Source

I came from a C#/Java background, so I'm trying to figure out how to create a C++ dll that behaves similar to a C# dll.

I have experimented with __declspec(dllexport) and __declspec(dllimport), but I have only managed to get it to work on static methods. I am sure this is due to my limited understanding.

How can I export classes in C++ (in its entirety including private members) and be able to instantiate them on the referencing end as I would with C#? Some pointer to an online resources/tutorial will also do it.

I started using the MFC dll template, and honestly I have no idea what 90% of them is for and why I'm inheriting from CWinApp. I tried to tag the class with CCppPracticeLibraryApp but it would no longer compile.

// CppPracticeLibrary.h : main header file for the CppPracticeLibrary DLL
//


#pragma once

#ifndef __AFXWIN_H__
    #error "include 'stdafx.h' before including this file for PCH"
#endif

#include "resource.h"       // main symbols

#ifdef CCppPracticeLibraryApp_EXPORTS
#define CCppPracticeLibraryApp_API __declspec(dllexport) 
#else
#define CCppPracticeLibraryApp_API __declspec(dllimport) 
#endif

// CCppPracticeLibraryApp
// See CppPracticeLibrary.cpp for the implementation of this class
//

class CCppPracticeLibraryApp : public CWinApp
{
public:
    CCppPracticeLibraryApp();
    static CCppPracticeLibraryApp_API void SayHelloWorld();
// Overrides
public:
    virtual BOOL InitInstance();

    DECLARE_MESSAGE_MAP()
};

the definition file:

//CppPracticeLibrary.cpp : Defines the initialization routines for the DLL.

#include "stdafx.h"
#include "CppPracticeLibrary.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define CCppPracticeLibraryApp_EXPORTS



BEGIN_MESSAGE_MAP(CCppPracticeLibraryApp, CWinApp)
END_MESSAGE_MAP()


// CCppPracticeLibraryApp construction

CCppPracticeLibraryApp::CCppPracticeLibraryApp()
{
    // TODO: add construction code here,
    // Place all significant initialization in InitInstance
}

void CCppPracticeLibraryApp::SayHelloWorld()
{
    printf( "Hello world");
}


// The one and only CCppPracticeLibraryApp object

CCppPracticeLibraryApp theApp;


// CCppPracticeLibraryApp initialization

BOOL CCppPracticeLibraryApp::InitInstance()
{
    CWinApp::InitInstance();

    return TRUE;
}

The client/referencing method

// TestConsoleApplication.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "TestConsoleApplication.h"
#include "CppPracticeLibrary.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    HMODULE hModule = ::GetModuleHandle(NULL);

    if (hModule != NULL)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
        {
            // TODO: change error code to suit your needs
            _tprintf(_T("Fatal Error: MFC initialization failed\n"));
            nRetCode = 1;
        }
        else
        {
            // TODO: code your application's behavior here.
            /*CCppPracticeLibraryApp* testCallingLibrary =  new CCppPracticeLibraryApp();
            testCallingLibrary->SayHelloWorld();*/
            CCppPracticeLibraryApp::SayHelloWorld();
        }
    }
    else
    {
        // TODO: change error code to suit your needs
        _tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
        nRetCode = 1;
    }

    return nRetCode;
}

I would like to be able to uncomment the following lines in the above code:

        /*CCppPracticeLibraryApp* testCallingLibrary =  new CCppPracticeLibraryApp();
        testCallingLibrary->SayHelloWorld();*/

Answer

bash.d picture bash.d · May 21, 2013

From MSDN

To export all of the public data members and member functions in a class, the keyword must appear to the left of the class name as follows:

class __declspec(dllexport) CExampleExport : public CObject
{ ... class definition ... };

Also, consider that there are more ways to do this, like .DEF-files. Take your time to read through the explanations on the MSDN-site.