Search code examples
c++pointersdllreturn-valuedllexport

How to return value from DLL using parameter of function as a pointer in C++?


I have a simple DLL:

dllmain.cpp:

#define MYDLLDIR        
#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    ...
}


void callByPtr(int *i) {
    
    (*i)++;
}

pch.h

#include "framework.h"

#ifdef MYDLLDIR
#define DLLDIR __declspec(dllexport) __stdcall
#else
#define DLLDIR __declspec(dllimport)
#endif

extern "C" {

    DLLDIR void callByPtr(int *i);
        
};

Client:

typedef void(__stdcall* callByPtr)(int*);

int main()
{
    HINSTANCE hDLL;

    hDLL = LoadLibrary(_T("MyDll.dll"));

    if (NULL != hDLL)
    {

        callByPtr myCall = (callByPtr)GetProcAddress(hDLL, "callByPtr");

        if (!myCall) {
            return EXIT_FAILURE;
        }

        int i = 10;

        int* ptri = &i;

        std::cout << "i " << i << std::endl;
        std::cout << "ptri " << ptri << std::endl;

        myCall(ptri);

        std::cout << "---- After Call ----\n";

        std::cout << "i " << i << std::endl;
        std::cout << "ptri " << ptri << std::endl;    

    }
}

Result:

---- Before Call ----

i = 10

ptri = 0025FB40

---- After Call ----

i = 11286192

ptri = 0025FB3C

The adress of ptri has changed and value was not 11.

How to implement this properly that I can get a value from DLL using method above?

Thank you!


Solution

  • Your exporting definitions are also not correct. Should be something like:

    #ifdef MYDLL_EXPORT
    #define MYDLLDIR  __declspec(dllexport)
    #else
    #define MYDLLDIR __declspec(dllimport)
    #endif
    

    and use the same macro (MYDLLDIR) for both export (dll, #MYDLL_EXPORT defined) and import(clients, #MYDLL_EXPORT NOT defined)

    You have to use the same calling convention for callByPtr in all places, in your case __stdcall (the default one is __cstdcall).

    In your pch.h then:

    MYDLLDIR void __stdcall callByPtr(int *i);