Hi I'm sorry I've seen that there is a lot of "unresolved external symbol error" questions, and I've seen them but none of the answers that I found fixed my error.
I've tested 2 ways to compile the DLL and use the HelloWorld method from SerialPort class. btw I'm using VS2019 community edition
Both ways are throwing the same error :
Error LNK2019 unresolved external symbol "public: void __thiscall SerialPort::HelloWorld(void)" (?HelloWorld@SerialPort@@QAEXXZ) referenced in function _main Test DriverCore C:\Users\$USER\source\repos\Test DriverCore\Test DriverCore\Main.obj 1
To what I've understood it's a linker error and the name of the method that I'm using is unresolved (not found) but I have no idea how to fix that (I thought that extern "C" prevented this to happen)
I've also tried to add #pragma comment(lib, "DriverCore.lib")
(with DriverCore.lib in the same Dir as DriverCore.h) but still nothing :/
Way 1 using a function to return a pointer to the class
DriverCore.h
#pragma once
#ifdef DRIVERCORE_EXPORTS
#define DLLCALL __declspec(dllexport)
#else
#define DLLCALL __declspec(dllimport)
#endif
class SerialPort
{
private:
bool connected = 0;
public:
SerialPort() {};
void HelloWorld();
bool isConnected() { return 0; };
int readSerialPort(char* buffer, unsigned int buf_size) { return 0; };
bool writeSerialPort(char* buffer, unsigned int buf_size) { return 0; };
};
extern "C" {
DLLCALL SerialPort* __stdcall CreateSerialPort();
};
DriverCore.cpp
#include "pch.h"
#include "DriverCore.h"
#include <iostream>
#define DRIVERCORE_EXPORTS
BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
return TRUE;
}
SerialPort* __stdcall CreateSerialPort()
{
return new SerialPort();
}
void SerialPort::HelloWorld()
{
std::cout << "Hello World !";
}
Main.cpp
#include "pch.h"
#include <Windows.h>
#include <iostream>
#include "DriverCore.h"
typedef SerialPort* (__stdcall *SerialPortImported) ();
int main()
{
// instantiate the dll location
HINSTANCE hDLL = LoadLibraryW(L"DriverCore.dll");
if (!hDLL) {
std::cout << "could not load the dynamic library" << std::endl;
return EXIT_FAILURE;
}
//Resolve Objects Addr
SerialPortImported pCSerialPort = (SerialPortImported) GetProcAddress(hDLL, "CreateSerialPort") ;
SerialPort* CSerialPort = pCSerialPort();
CSerialPort->HelloWorld();
return 0;
}
Way 2 without using extern "c" {...} but using __declspec directly onto the class declaration
DriverCore.h
#pragma once
#ifdef DRIVERCORE_EXPORTS
#define DLLCALL __declspec(dllexport)
#else
#define DLLCALL __declspec(dllimport)
#endif
class DLLCALL SerialPort
{
private:
bool connected = 0;
public:
SerialPort() {};
void HelloWorld();
bool isConnected() { return 0; };
int readSerialPort(char* buffer, unsigned int buf_size) { return 0; };
bool writeSerialPort(char* buffer, unsigned int buf_size) { return 0; };
};
DriverCore.cpp
#include "pch.h"
#include "DriverCore.h"
#include <iostream>
#define DRIVERCORE_EXPORTS
BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
return TRUE;
}
void SerialPort::HelloWorld()
{
std::cout << "Hello World !";
}
Main.cpp
#include "pch.h"
#include <Windows.h>
#include <iostream>
#include "DriverCore.h"
int main()
{
// instantiate the dll location
HINSTANCE hDLL = LoadLibraryW(L"DriverCore.dll");
if (!hDLL) {
std::cout << "could not load the dynamic library" << std::endl;
return EXIT_FAILURE;
}
//Resolve Objects Addr
SerialPort* pSerialPort = (SerialPort*) GetProcAddress(hDLL, "SerialPort") ;
pSerialPort->HelloWorld();
return 0;
}
Thanks a lot in advance for your help !
You are calling HelloWorld
which is missing its implementation in your application.
There is some fundamental misunderstanding about how C++ executables are compiled and linked against DLLs.
Since you are not linking with the dll and only load it at runtime, the linker correctly complains about the missing HelloWorld
method.
Extern "C" is irrelevant here.