简体   繁体   中英

How to export a function of a regular MFC DLL that is statically linked to MFC to use with a non MFC Win32 Console App in C++

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

  1. What i am doing wrong?
  2. 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 the SerialApp class, and cannot know about it since SerialApp is derived from CWinApp 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 the SerialApp 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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM