1

I have a fucntion in dynamic library which looks like:

namespace Dll {
    int MyDll::getQ() {
        srand(time(0));
        int q = rand();
        while (!isPrime(q) || q < 100) {
            q = rand();
        }
        return q;
    }
}

Function getQ() in .h file:

#ifdef _EXPORT
#define DLL_EXPORT __declspec(dllexport) 
#else
#define DLL_EXPORT __declspec(dllimport) 
#endif

namespace Dll
{
    class MyDll
    {
    public:
        static DLL_EXPORT int __stdcall getQ();
    }
}

And finally LoadLibrary peace of code from another consoleApp:

typedef int(__stdcall *CUSTOM_FUNCTION)();
int main()
{

    HINSTANCE hinstance;
    CUSTOM_FUNCTION proccAddress;
    BOOL freeLibrarySuccess;
    BOOL proccAddressSuccess = FALSE;
    int result;

    hinstance = LoadLibrary(TEXT("Dll.dll"));
    if (hinstance != NULL)
    {
        proccAddress = (CUSTOM_FUNCTION)GetProcAddress(hinstance, "getQ");
        if (proccAddress != NULL)
        {
            proccAddressSuccess = TRUE;
            result = (*proccAddress)();
            printf("function called\n");
            printf("%d", result);
        }
        freeLibrarySuccess = FreeLibrary(hinstance);
    }

    if (!hinstance)
        printf("Unable to call the dll\n");

    if (!proccAddressSuccess)
        printf("Unable to call the function\n");
}

So I tried to fix this several times but I always get "Unable to call the function". The code connects to the library so the problem is somewhere near the function. I'll appreciate if someone will point me on my mistake.

drescherjm
  • 10,365
  • 5
  • 44
  • 64
Storm
  • 557
  • 1
  • 8
  • 25
  • 1
    You should look up `name mangling in C++`, tl;dr; no function named `"getQ"` is exported from library. – user7860670 Apr 01 '18 at 15:13
  • I will but if I change _stdcall to _cdecl there's no change – Storm Apr 01 '18 at 15:17
  • 1
    @Storm `_stdcall` and `_cdecl` only is calling convention. has no effect on mangling. – Afshin Apr 01 '18 at 15:18
  • @Afshin I mean since I am using _stdcall I am supposed to write _getQ@0 instead of getQ() but that gives zero effect. Am I wrong? – Storm Apr 01 '18 at 15:23
  • @Storm I don't know what your function's mangled name is but I think your mangled name is incorrect or it should have class and namespace name in it too. This is the reason why I always recommend to `extern "C"` your functions for dynamic loading. – Afshin Apr 01 '18 at 15:28
  • @Afshin: The calling convention *does* have an effect on name decoration. This is documented (see [Format of a C decorated name](https://learn.microsoft.com/en-us/cpp/build/reference/decorated-names#FormatC)). – IInspectable Apr 02 '18 at 17:55

1 Answers1

1

You are missing an Extern "C".

If you don't, names will be c++ mangled and you cannot find them with getQ name only. In addition, it will not be reliable to do so, because name mangling may change.

Another topic is here to: _stdcall vs _cdecl

Afshin
  • 8,839
  • 1
  • 18
  • 53
  • if you use the depends tool, you can find the mangled name, but depending on it is somewhat dangerous, as the compiler is free to change its scheme more or less at will – nate Apr 01 '18 at 15:30
  • @nate yea, I personally strongly against using mangled c++ names for export too for the same reason. – Afshin Apr 01 '18 at 15:32
  • Exporting managed names is often quite a good idea. Anyway, surely it would have been better just to close the question as a duplicate. – David Heffernan Apr 01 '18 at 15:39
  • I finally get it after I saw the real function name throught the dependecny walker. Thanks everyone. The real name is: ?getE@MyDll@Dll@@SGHXZ btw – Storm Apr 01 '18 at 15:43
  • @DavidHeffernan why exporting mangled names is a good idea? for parameter checking? at least I don't think it is a good idea for dynamic loading. – Afshin Apr 01 '18 at 16:06
  • It's just a name. It's no harder to work with a mangled name. And it means you find out when you inadvertently change one of the parameters and rebuild the dll. – David Heffernan Apr 01 '18 at 16:19
  • @DavidHeffernan Mangling is not part of the Windows ABI, so different compilers are free to mangle however they like. (For example, gcc and MSVC mangle differently.) Exporting mangled names prevents Interop. Also, 32-bit and 64-bit mangling can vary. Even version-to-version within a compiler can change. – Raymond Chen Apr 01 '18 at 19:22
  • This answer (and comments) appear to suggest, that `extern "C"` were to disable name mangling. That's not the case. `extern "C"` simply uses a different name decoration scheme. This question is incomplete at best, but actually it is rather misleading. – IInspectable Apr 02 '18 at 12:33