-1

I got unresolved external symbol error when trying to use a function from external dll! Here is the code from exported dll:

//MathFunc.h
#pragma once

template <class T>
class MyMathFuncs
{
public:
    T Add(T a, T b);
};

extern "C" {
    MYAPI MyMathFuncs<int>* createInst(){
        return new MyMathFuncs<int>;
    }
}

//MathFunc.cpp
#include "MathFuncsDll.h"
#include <stdexcept>

using namespace std;

template <class T>
T MyMathFuncs<T>::Add(T a, T b)
{
    return a + b;
}

After compiling this project, I got .dll and .lib files. After that, I created a new project and added .dll file to output directory and .lib file to linker->Input->Additional dependencies. Here is code in the new project:

//main.cpp
#include <iostream>
#include "MathFuncsDll.h"

using namespace std;

int main(){
    MyMathFuncs<int> * pObj = createInst();
    cout << pObj->Add(1, 1) << endl;

    cin.get();
    return 0;
}

However, when I compile it causes an error:

Error   1   error LNK2001: unresolved external symbol "public: int __thiscall       MyMathFuncs<int>::Add(int,int)" (?Add@?$MyMathFuncs@H@@QAEHHH@Z)    N:\Play around Code\DllApplication\DllApplication\main.obj

Is it because I have imported the dll wrongly or what? I have checked all the project's settings in the new project which included additional includes and additional dependencies(for .lib).

doptimusprime
  • 9,115
  • 6
  • 52
  • 90
OhMyGosh
  • 1,579
  • 4
  • 18
  • 31
  • @user657267: Bent problem is different. Template is already in header file. – doptimusprime Aug 15 '14 at 03:02
  • @user657267 The entire class template has to be in the .h file. Your class is not entirely in the .h file you have an implementation in MathFunc.cpp. – shf301 Aug 15 '14 at 03:10
  • Thanks, guys! I never heard about it before, it's really good to know! I am trying other suggestions see how it works! I will update the status when i get the result – OhMyGosh Aug 15 '14 at 03:31
  • @dbasic `//MathFunc.cpp` doesn't look like a header to me. – user657267 Aug 15 '14 at 03:32
  • @user657267 was right! The template class implementation must be in header file. When I try to remove the template and add __declspec(dllexport) to class name. It works! – OhMyGosh Aug 15 '14 at 03:39
  • Hi @user657267, I just read the link you commented above, and realized that actually my code is the same as on of the common solution. But how come it's not working here? – OhMyGosh Aug 15 '14 at 04:40
  • @Bent Your code above **isn't** the same as the linked question, you have at least one class template member function defined in a separate compilation unit (`MathFunc.cpp`), this will not work unless you preinstantiate templates for the types you want to use. You will either have have to put the member function definitions inside `MathFunc.h`, or `#include MathFunc.cpp` in `MathFunc.h` (if the latter **do not compile MathFunc.cpp separately**, also it will not be able to contain non-inline non-template functions). – user657267 Aug 15 '14 at 05:31

1 Answers1

0

In the class definition, you need to specify __declspec(dllexport) while generating dll and __declspec(dllimport) while using it which I think you are doing with MYAPI.

Change class definition as follows:

template <class T>
class MYAPI MyMathFuncs
{
public:
    T Add(T a, T b);
};
doptimusprime
  • 9,115
  • 6
  • 52
  • 90