c++windowsdllgetprocaddress

GetProcAddress function returning NULL


I tried to load C++ dll dynamically, first I loaded the dll using "LoadLibrary" function and it is getting its handle correctly. After that I tried to get the function pointer of DLL file function using "GetProcAddress", it is returning NULL. Please find my DLL code and testing application code and let me know where is going wrong in the code.

dummy2.h

namespace newer
{
  class dllclass
  {
    public:
        static __declspec(dllexport) int run(int a,int b);
  };
}

dummy2.cpp

#include <iostream>
using namespace std;

#include "dummy2.h"

namespace newer
{
  int dllclass::run(int a,int b)
  {
    return a+b;
  }
}

dummy1.cpp

#include "stdafx.h" 
#include <windows.h>

#include <iostream>
using namespace std;
typedef int (*Addition)(int,int);

int _tmain(int argc, _TCHAR* argv[])
{
  Addition add;
  HINSTANCE hDLL;
  hDLL = LoadLibrary(TEXT("Dummy2.dll"));

  add = (Addition)GetProcAddress(hDLL, "run");  

  getchar();
  return 0;
}

Please refer above code and guide me.


Solution

  • It's because the name is mangled (i.e. the name of the function is not "run" but something different).

    Your code will work with (for MSVC 2013 where I tested):

    add = (Addition)GetProcAddress(hDLL, "?run@dllclass@newer@@SAHHH@Z");
    cout << add(1, 2) << endl;
    

    In general, if you want to load a class via plugin, your best shot is to use virtual interface. An example:

    //dummy2.h
    namespace newer
    {
      class dllclass_interface
      {
        public:
            virtual int run(int a,int b) = 0;
     };
    
    }
    
    extern "C" __declspec(dllexport) newer::dllclass_interface* getDllClass();
    

    //dummy2.cpp
    #include <iostream>
    using namespace std;
    
    #include "dummy2.h"
    
    namespace newer
    {
      class dllclass: public dllclass_interface
      {
        public:
            virtual int run(int a,int b);
     };
    
      int dllclass::run(int a,int b)
      {
        return a+b;
      }
    }
    
    extern "C" newer::dllclass_interface* getDllClass()
    {
        static newer::dllclass instance;
        return &instance;
    }
    

    typedef newer::dllclass_interface* (*GetClassFunc)();
    
    GetClassFunc getClassFunc = (GetClassFunc)GetProcAddress(hDLL, "getDllClass");
    
    newer::dllclass_interface* dllClass = getClassFunc();
    cout << dllClass->run(a, b) << endl;