1

I'm writing a C++ programm that dynamically loads a dll at runtime and calls a function within that dll. Thats working fine but now i want to call a function defined in my C++ programm from within the dll.

My main.cpp looks like this:

#include <Windows.h>
#include <iostream>

typedef void(*callC)(int);

int main()
{
    HINSTANCE dllHandle = LoadLibrary("D:\Libraries\lib.dll");

    callC func = (callC)GetProcAddress(dllHandle, "callC");

    func(42);

    FreeLibrary(dllHandle);
}

// I want to call this function from my dll
void callableFromDll(){
}

The part of the dll thats accessed is writtin in C and looks like as follows:

#include <stdio.h>

void callC(int);

void callC(int i){
    print(i);

    // Call the C++ function
    //callableFromDll();
}

I've read about the __declspec(dllimport) and __declspec(dllexport) attributes but im really new to C++ and not sure if these are the right thing to use and if so, how to use them.

Painkiller
  • 115
  • 9

1 Answers1

5

In your C++ program:

extern "C" _declspec(dllexport) void callableFromDll(int value) {
    printf("This function was called from the main process. Value: %d\n", value);
}

In your DLL:

typedef void(*callableFromDll)(int);
callableFromDll func;

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        func = (callableFromDll)GetProcAddress(GetModuleHandle(NULL), "callableFromDll");
        func(69);
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:

        break;
    }
    return TRUE;
}
GetModuleHandle(NULL)

Returns the parent's executable handle.

Console output from the exe when LoadLibrary has loaded the DLL:

This function was called from the main process. Value: 69

cppfunction.exe (process 16336) exited with code 0.
Press any key to close this window . . .

extern "C" tells the compiler to not encode the function's name into a unique name. The compiler encodes names so that linkers can separate common function or variable names.

See extern "C" and extern "C++" function declarations, Exporting from a DLL Using __declspec(dllexport) and Importing function calls using __declspec(dllimport).

  • 1
    DLL_PROCESS_ATTACH is not in the console output, right? – manuell May 11 '20 at 13:12
  • So did I understand this right: the DllMain function is called when the dll is loaded by the main program? Does that mean i have to initialize all the external functions I want to use during this function call? – Painkiller May 12 '20 at 07:05
  • 1
    DllMain gets called when the dll is loaded. You don't have to initialize the functions inside DllMain, you can initialize them outside of DllMain like so: `callableFromDll func = (callableFromDll)GetProcAddress(GetModuleHandle(NULL), "callableFromDll");` – Dennis Stanistan May 12 '20 at 08:32