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)
MFC DLL Header File Content
// 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()
};
MFC DLL Definition File Content
// 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";
}
}
Win32 Console Application Content
#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.
Questions
- What i am doing wrong?
- Is this even possible?
Thank you!
__declspec(dllexport) void __cdecl SerialApp::Init()
Is that a typo? The function that you try to__declspec(dllimport)
is a free function, not a member ofSerialApp
. – dxivclass SerialApp : public CWinApp { public: SerialApp(); __declspec(dllexport) void __cdecl SerialApp::Init();
Thank you! – swartkattmain()
you declare a function namedInit()
, for which you did not provide an implementation (definition), so the linker fails. The member functionInit()
is a different function. It can be invoked through a class instance (egpSerialApp->Init()
), or using the class name (ieSerialApp::Init()
) if it was a static member function).Init()
will generate code and try to link to function namedInit()
, that it not member of any class. It's the same as::Init()
(which is often used to tell the compiler to call a function in the global namespace rather the class). – Constantine Georgiou__declspec(dllimport) void __cdecl Init(void);
inside the main() function, I thought and hoped that the compiler can understand that i want to use the Init() method inside the Serial.lib and Serial.dll that i provide. > What is the problem with this part?typedef void(*Init_t)(void); Init_t Serial = (Init_t)GetProcAddress(lib, "Init");
– swartkattSerialApp::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. As for C#, which you only brought into the picture in the last comment, you cannot directly import any C++ classes or member functions, anyway. – dxiv