How to export C ++ class as dll?

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

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

How can I export classes in C ++ (in full, including private members), and be able to create them at the end of the link, as with C #? Some pointers to online resources / tutorial will also do this.

I started using the MFC dll template, and frankly, I have no idea what 90% of them are and why I inherit CWinApp. I tried tagging the CCppPracticeLibraryApp class, but it will 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() }; 

definition file:

//CppPracticeLibrary.cpp: Defines the initialization procedures 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; } 

Client / link 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 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();*/ 
+6
source share
4 answers

From MSDN

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

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

Also think that there are more ways to do this, such as .DEF -files. Take the time to read the explanations on the MSDN website.

+4
source

With __declspec (dllexport) and __declspec (dllimport), you simply create an api that you can use to export methods or members from your DLL. By exporting these methods, you can access it from another dlll. You can create a header file in which you define your export macro.

  ifdef MYPROJECT_EXPORTS define MYPROJECT_EXPORTS__declspec( dllexport ) else define MYPROJECT_EXPORTS__declspec( dllimport ) endif 

and when you declare your method, if you want to export it, you just need to put your macro before the method declaration, for example:

 MYPROJECT_EXPORTS void myMethod(); 

And also you should add your symbol to the Preprocesor definitions (in MS Visual Studio β†’ Project Properties β†’ C / C ++ β†’ Preprocessor β†’ Prerocessor Definitions.

+5
source

To export all class members, you can include declspec in this declaration, as shown below.

 class __declspec(dllexport) ExportedClass { //.... }; 
+3
source

You should read this very interesting CodeProject article on this subject.

Please note that if you create DLLs with C ++ classes at the borders (including MFC classes or STL classes), your DLL client should use the same version of the VC ++ compiler and the same CRT flavor (for example, multi-threaded DLL debug CRT , multi-threaded CRT DLL release and other "finer" settings, for example the same _HAS_ITERATOR_DEBUGGING settings) for creating EXEs that will use the DLL.

Instead, if you export a clean C interface from a DLL (but you can use C ++ inside a DLL, like the Win32 API), or if you create a COM DLL, your DLL clients can use a different version of the VC ++ compiler (and even other CRTs) for using your DLL.

In addition, also note that the above article defines β€œC ++ Mature Approach” (i.e. using an abstract interface).

+3
source

Source: https://habr.com/ru/post/945475/


All Articles