Ok, so, DLLs are getting mad annoying. Either because I'm a fool or they are really that complex.
I'm trying to have a DLL which contains a class and then export that class and use it via Run-Time Dynamic Linking, i.e. using LoadLibrary and GetProcAddress functions, without needed to link to a .lib.
I read that it's better to instead of exporting the class itself, you should export a function which returns an instance of said class. Something like this;
extern "C" {
    Threader __declspec(dllexport)* CreateClass()
    {
        return new Threader();
    }
};
How do I then do the whole "GetProcAddress" in the main to access this function. I can't seem to get it to work. I can export a regular function that just returns an int this way no issue, but with the class return I'm struggling. When I try to call the function, the compilier throws error;
LNK2019 unresolved external symbol "public: __cdecl Threader::Threader(void)" (??0Threader@@QEAA@XZ) referenced in function CreateClass
Here's my source code;
Main.cpp
#include <iostream>
#include "Threader.h"
#include "GetClass.h"
#include <Windows.h>
typedef int(__cdecl* MYPROC)(LPCWSTR);
typedef Threader* (* GETMYCLASS)(LPCWSTR);
int wmain()
{
    HINSTANCE hinstLib;
    MYPROC ProcAdd;
    GETMYCLASS ClassAdd;
    BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
    hinstLib = LoadLibrary(TEXT("ThreaderDLL.dll"));
    if (hinstLib != NULL)
    {
        std::cout << "DLL Loaded" << std::endl;
        ProcAdd = (MYPROC) GetProcAddress(hinstLib, "ThreadFunc");
        GETMYCLASS ClassAdd = (GETMYCLASS) GetProcAddress(hinstLib, "CreateClass");
        if (NULL != ProcAdd && NULL != ClassAdd)
        {
            std::cout << "Func Loaded, Class Loaded"<<std::endl; //**This line runs so ClassAdd is NOT empty**
            fRunTimeLinkSuccess = TRUE;
            ThreadFunc();
            Threader* threader = CreateClass(); //This wont work causes build to fail
        }
        // Free the DLL module.
        fFreeResult = FreeLibrary(hinstLib);
    }
    int i = 0;
    double j = 0;
    std::cout << "Hello World!\n";
    Sleep(2000);
    std::cout << "WakaWaka" << std::endl;
    Sleep(2000);
    return i;
}
Threader.h
#pragma once
#include <thread>
#include <iostream>
#include <vector>
#include <atomic>
#include <mutex>
class Threader
{
public:
    Threader();
    ~Threader();
    void makeThread();
    int ThreadFunc();
    std::vector<std::thread> threads;
    std::atomic<bool> running = true;
    static std::mutex mtx_;
    std::atomic<int> i = 0;
private:
};
extern "C" {
    Threader __declspec(dllexport)* CreateClass()
    {
        return new Threader();
    }
};
extern "C" {
    int __declspec(dllexport) __cdecl ThreadFunc()
    {
        int i = 0;
        while (i < 500)
        {
            std::cout << i << "\n";
            i++;
        }
        return 0;
    }
};
Threader.cpp
#include "Threader.h"
#include <Windows.h>
std::mutex Threader::mtx_;
Threader::Threader()
{
}
Threader::~Threader()
{
    //running = false;
    std::cout << "Killing Class and joining threads" << std::endl;
    for (auto& t : threads)
    {
        t.join();
    }
}
void Threader::makeThread()
{
    std::cout << "Making Class thread" << std::endl;
    //std::thread thread(&Threader::ThreadFunc, this);
    threads.push_back(std::thread(&Threader::ThreadFunc, this));
    //thread.join();
    //return 0;
}
int Threader::ThreadFunc()
{
    std::cout << "Class Thread Started" << std::endl;
    while (running)
    {
        while (i < 100)
        {
            std::lock_guard<std::mutex> lck(mtx_);
            //std::cout << "i = " << i << "\n";
            i++;
            Sleep(1000);
        }
        running = false;
    }
    std::cout << "Class Thread Ending" << std::endl;
    return 0;
}
Do I have to put the declaration of CreateCLass in the .h and the implementation in the .cpp? I know it has something to do with the compilier not finding the implementaiton or something like that. But I'm pretty sure I tried that and it still didn't work.
Plz help.
Aucun commentaire:
Enregistrer un commentaire