1

I have the following code, header and source code, that I am trying to build a dll and lib to use in another project. I feel like I have followed the proper steps to export both a dll and lib, but the lib file just isn't showing up. I have checked out other people's questions and have added the EXPORTS to the Preprocessor definitions which someone else said fixed their problem but not mine.

Matrix.h

#ifdef MATRIX_EXPORTS
#define MATRIX_API __declspec(dllexport)
#else
#define MATRIX_API __declspec(dllimport)
#endif

#include <vector>

using namespace std;

template<typename T> class MATRIX_API Matrix
{
public:
typedef T value_type;
~Matrix();
Matrix();
Matrix(int rows, int columns);
int height;
int width;
int stride;
size_t size;

T &GetElement(int row, int column);
void SetElement(int row, int column, T value);
void SetElements(vector<T> value);
vector<T>& GetElements();
T* GetPointer();
void Transpose(Matrix<T> &aMatrix);
void Pivot(Matrix<T>&A, Matrix<T>&P);
void LU_Decomp(Matrix<T>&A, Matrix<T>&L, Matrix<T>& U, Matrix<T>& P);
bool isSingular(Matrix<T>&L, Matrix<T>&U);
void CreateIdentity(Matrix<T>&I);*/
private:
vector<T> elements;
T* firstElement;
};

Matrix.cpp

#include "Matrix.h"
#include <vector>
#include <iostream>

using namespace std;

template<typename T>
Matrix<T>::~Matrix()
{
}

template<typename T>
Matrix<T>::Matrix()
{
}

template<typename T>
Matrix<T>::Matrix(int rows, int columns)
{
height = rows;
width = columns;
stride = columns; //in row major order this is equal to the # of columns
elements.resize(rows*columns);
firstElement = elements.data();
size = height*width*sizeof(T);
}

template<typename T>
MATRIX_API T &Matrix<T>::GetElement(int row, int column)
{
return elements[row*width + column]; //row major order return
}

template<typename T>
MATRIX_API vector<T>& Matrix<T>::GetElements()
{
return elements; //row major order return
}

template<typename T>
MATRIX_API void Matrix<T>::SetElement(int row, int column, T value)
{
elements[row*width + column] = value; //row major order return
}

template<typename T>
MATRIX_API void Matrix<T>::SetElements(vector<T> value)
{
elements = value;
}

template<typename T>
MATRIX_API T* Matrix<T>::GetPointer()
{
return firstElement;
}

template<typename T>
MATRIX_API void Matrix<T>::Transpose(Matrix<T> &aMatrix)
{
Matrix<T> theTranspose(aMatrix.width,aMatrix.height);

for (int i = 0; i < theTranspose.height; i++)
{
    for (int j = 0; j < theTranspose.width; j++)
    {
        theTranspose.SetElement(i,j,aMatrix.GetElement(j,i));
    }
}

*this = theTranspose;
}


template<typename T>
//Calculates C=A*B 
MATRIX_API Matrix<T> operator * (Matrix<T> A, Matrix<T> B)
{
Matrix<T> C(A.height, B.width);

for (int m = 0; m < C.height; m++)
{
    for (int p = 0; p < C.width; p++)
    {
        T value = (T)0;
        for (int n = 0; n < A.width; n++)
        {
            value += A.GetElement(m,n)*B.GetElement(n,p);
            C.SetElement(m,p,value);
        }
    }
}

return C;
}

template<typename T>
MATRIX_API Matrix<T> operator + (Matrix<T> &A, Matrix<T> &B)
{
if (A.height != B.height || A.width != B.width)
{
    cout<<" \n can't add these two matrices. They are not of equal dimensions.         Program Quitting"<<endl;
}

Matrix<T> sum(A.height, A.width);
T value = NULL;

for (int i = 0; i < A.height; i++)
{
    for (int j = 0; j < A.width; j++)
    {
        value = A.GetElement(i,j) + B.GetElement(i,j);
        sum.SetElement(i,j, value);
    }
}

return sum;
}

template<typename T>
MATRIX_API Matrix<T> operator += (Matrix<T> &A, Matrix<T> &B)
{
A = A + B;

return A;
}

template<typename T>
MATRIX_API void Matrix<T>::Pivot(Matrix<T>&A, Matrix<T>&P)
{
for (int i = 0; i < A.height; i++)
{
    for (int j = 0; j < A.height; j++)
    {
        P.SetElement(i,j,i==j);
    }
}

for (int i = 0; i < A.height; i++)
{
    int max_j = i;

    for (int j = i; j < A.height; j++)
    {
        if (fabs(A.GetElement(j,i)) > fabs(A.GetElement(max_j, i)))
        {
            max_j = j;
        }
    }

    if (max_j != i)
    {
        for (int k = 0; k < A.height; k++)
        {
            T temp = P.GetElement(i,k);
            P.SetElement(i,k,P.GetElement(max_j,k));
            P.SetElement(max_j,k,temp);
        }
    }
}
}

template<typename T>
MATRIX_API void Matrix<T>::LU_Decomp(Matrix<T>&A, Matrix<T>&L, Matrix<T>& U, Matrix<T>& P)
{
int size = L.height;
pivot(A,P);

Matrix<T> Aprime;
Aprime = Aprime.prod(P,A);

for (int i = 0; i < size; i++)
{
    L.SetElement(i,i,1);
}

for (int i = 0; i < size; i++)
{
    for (int j = 0; j < size; j++)
    {
        T s;

        if (j <= i)
        {
            s = 0;
            for (int k = 0; k < j; k++)
            {
                s+=L.GetElement(j,k)*U.GetElement(k,i);
            }

            T value = Aprime.GetElement(j,i) - s;
            U.SetElement(j,i,value);
        }

        if (j >= i)
        {
            s = 0;
            for (int k = 0; k < i; k++)
            {
                s+= L.GetElement(j,k)*U.GetElement(k,i);
            }

            T value = (Aprime.GetElement(j,i) - s)/U.GetElement(i,i);
            L.SetElement(j,i,value);
        }
    }
}
}

template<typename T>
//Take determinant of L and U matrices of LU decomposition to determine if parent matrix is singular
MATRIX_API bool Matrix<T>::isSingular(Matrix<T>&L, Matrix<T>&U)
{
T detL = L.GetElement(0,0);
T detU = U.GetElement(0,0);

for (int i = 1; i < L.height; i++)
{
    detL = detL*L.GetElement(i,i);
    detU = detU*L.GetElement(i,i);
}

if (detL*detU == 0)
{
    return true;
}
else
{
    return false;
}
}
user3390212
  • 125
  • 1
  • 1
  • 9

1 Answers1

1

Maybe not the problem, but you should add MATRIX_EXPORTS not EXPORTS to the preprocessor definitions. Also you need to instantiate you template inside the library otherwise no exports will be present (assuming you are not exporting anything else but your templated class)

Jens Munk
  • 4,627
  • 1
  • 25
  • 40
  • Yea when I said EXPORTS I mean MATRIX_EXPORTS. I also moved everything from the header file above into the cpp. Any includes that I had and the #ifdef MATRIX_EXPORTS, etc I kept in the header file. It still doesn't build a library – user3390212 Mar 27 '14 at 15:02
  • Did you ensure you are instantiating the template inside the library? If you haven't solved, send me code and I will fix it :-) – Jens Munk Apr 08 '14 at 20:52