I am very new in C++ world and this kind of task. I am having a hard time to resolve this issue. Any help is kindly appreciated!
I have created a regular MFC DLL that is statically linked to MFC. (This is the first time i ever created a MFC project)
// Serial.h
#pragma once
#ifndef __AFXWIN_H__
#error "include 'pch.h' before including this file for PCH"
#endif
#include "resource.h" // main symbols
class SerialApp : public CWinApp
{
public:
SerialApp();
__declspec(dllexport) void __cdecl SerialApp::Init();
public:
virtual BOOL InitInstance();
DECLARE_MESSAGE_MAP()
};
// Serial.cpp
#pragma once
#include "pch.h"
#include "framework.h"
#include "Serial.h"
#include <iostream>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
BEGIN_MESSAGE_MAP(SerialApp, CWinApp)
END_MESSAGE_MAP()
SerialApp::SerialApp()
{
}
SerialApp theApp;
BOOL SerialApp::InitInstance()
{
CWinApp::InitInstance();
return TRUE;
}
extern "C"
{
__declspec(dllexport) void __cdecl SerialApp::Init()
{
AfxDebugBreak();
std::cout << "Succeded";
}
}
#include <iostream>
#include <Windows.h>
int main()
{
//Load the DLL
HMODULE lib = LoadLibrary(L"D:\\C++ PROJECTS\\serial\\Debug\\Serial.dll");
//Create the function
typedef void(*Init_t)(void);
Init_t Serial = (Init_t)GetProcAddress(lib, "Init");
std::cout << GetLastError(); // This output's 127
if (!Serial) {
//ERROR. Handle it.
}
__declspec(dllimport) void __cdecl Init(void);
//Init(); //LNK2019 unresolved external symbol "__declspec(dllimport) void __cdecl Init(void)"
std::getchar();
}
When i use this approach:
__declspec(dllimport) void __cdecl Init(void);
Init();
//I am getting the linker error LNK2019 unresolved external symbol "__declspec(dllimport) void __cdecl Init(void)"
When i use this approach:
typedef void(*Init_t)(void);
Init_t Serial = (Init_t)GetProcAddress(lib, "Init");
std::cout << GetLastError();
//I am getting error code 127 from the GetLastError() function. (The specified procedure could not be found)
When i use this approach:
#include "Serial.h"
int main()
{
SerialApp pSerial;
pSerial.Init();
std::getchar();
}
//Serial.h forces me to include 'pch.h' before itself. if i include 'pch.h' into Win32 Console App before Serial.h It end's up with about 1000's of errors.
For Win32 Console Application Project:
1. C/C++ -> General -> Additional Include Directories is set to: D:\C++ PROJECTS\serial\Serial
2. Linker -> Input -> Additional Dependencies is set to : Serial.lib
3. Both Serial.lib and Serial.dll are included in the project and in the Debug folder.
4. Both MFC Dll Project and Win32 Console Projects are compiled in Debug x86 mode.
- What i am doing wrong?
- Is this even possible?
Thank you!
The question is resolved by @dxiv's comment:
You cannot import a member function like
SerialApp::Init
to a non-MFC app, because that app does not know about theSerialApp
class, and cannot know about it sinceSerialApp
is derived fromCWinApp
which is an MFC class, while your app is non-MFC. If you want to export a free function from the DLL, then make it__declspec(dllexport) void __cdecl Init(void);
outside theSerialApp
class, or any class for that matter.
1. I removed the declaration __declspec(dllexport) void __cdecl SerialApp::Init();
from the header file.
2. Rewrite the definition of Init() in the Serial.cpp file as:
extern "C"
{
__declspec(dllexport) void __cdecl Init()
{
std::cout << "Succeded";
}
}
3. I call the function in Win32 Console App as:
int main()
{
//Load the DLL
HMODULE lib = LoadLibrary(L"D:\\C++ PROJECTS\\serial\\Debug\\Serial.dll");
//Create the function
typedef void(*Init_t)(void); // <- You can name Init_t whatever you want.
Init_t Serial = (Init_t)GetProcAddress(lib, "Init");
if (!Serial) {
std::cout << GetLastError();
return 1;
}
Serial(); //<- Init() Function Call from Serial.dll
std::getchar();
return 0;
}
And all worked great!
Thank you everyone, who make time to read and answer my Question!