saad ghadiry
saad ghadiry

Reputation: 29

dynamic link library c++

I was writing a c++ library and testing it, I compiled it using command line tools without using any ide, when I compiled the library and the test program no error found, but when i run the program it sometimes generate an error and sometimes work correctly, when i get an error it is: "The specified procedure could not be found" I used dllexport in my library header and pragma comment (lib,...) to link in my test and my compile command is like thiis:

cl -o library.dll quaternion.cpp /link /DLL
cl program.cpp

the complete run output:

q = 10 + 10 i + 10 j + 10 k
p = 1 + 1 i + 1 j + 1 k
testing *= operator:
q = -20 + 20 i + 20 j + 20 k
testing * operator:
q = -20 + 20 i + 20 j + 20 k
testing /= operator:
q = 10
testing / operator:
q = 10
testing += operator:
q = 11 + 11 i + 11 j + 11 k
testing + operator:
q = 11 + 11 i + 11 j + 11 k
testing -= operator:
q = 9 + 9 i + 9 j + 9 k
testing - operator:
q = 9 + 9 i + 9 j + 9 k
testing = operator:
q = 1 + 1 i + 1 j + 1 k
testing ^ operator:
power 2:
q = -200 + 200 i + 200 j + 200 k
power 3:
q = -80000 - 80000 i - 80000 j - 80000 k
power 4:
q = -1.28e+010 + 1.28e+010 i + 1.28e+010 j + 1.28e+010 k
power 0:
q = 1
testing norm function:
||q|| = 20

and the error run output:

q = 10 + 10 i + 10 j + 10 k
p = 1 + 1 i + 1 j + 1 k
testing *= operator:
q = -20 + 20 i + 20 j + 20 k
testing * operator:
q = -20 + 20 i + 20 j + 20 k
testing /= operator:
q = 10
testing / operator:
q = 10
testing += operator:
q = 11 + 11 i + 11 j + 11 k
testing + operator:
error!The specified procedure could not be found.

and here is my code:

quaternion.h

#include <cstdlib>
#include <cmath>
#include <string>
#include <sstream>
#include <iostream>
#ifndef QUATERNION_H
#define QUATERNION_H

#ifdef EXPORTING_DLL
    #define DllExport  __declspec( dllexport )
#else
    #define DllExport  __declspec( dllimport )
#endif
using namespace std;

class Quaternion
{
    public:
        float X, Y, Z, W;
        DllExport Quaternion();
        DllExport Quaternion(const Quaternion& orig);
        DllExport Quaternion(float x, float y, float z, float w);
        DllExport ~Quaternion();

        //base math
        DllExport Quaternion & operator +(const Quaternion &q);
        DllExport Quaternion & operator +=(const Quaternion &q);

        DllExport Quaternion & operator -(const Quaternion &q);
        DllExport Quaternion & operator -=(const Quaternion &q);

        DllExport Quaternion & operator *(const Quaternion &q);
        DllExport Quaternion & operator *=(const Quaternion &q);

        DllExport Quaternion & operator /(const Quaternion &q);
        DllExport Quaternion & operator /=(const Quaternion &q);

        DllExport Quaternion & operator =(const Quaternion &q);

        DllExport Quaternion & operator ^(int i);

        //aditional functions
        DllExport double Norm();// ||q||
        DllExport string ToString();
    private:
};

#endif

quaternion.cpp:

#include "quaternion.h"

Quaternion::Quaternion()
{
    X = 0;
    Y = 0;
    Z = 0;
    W = 0;
}

Quaternion::Quaternion(const Quaternion& orig) 
{
    X = orig.X;
    Y = orig.Y;
    Z = orig.Z;
    W = orig.W;
}


Quaternion::Quaternion(float x, float y, float z, float w)
{
    X = x;
    Y = y;
    Z = z;
    W = w;
}

Quaternion::~Quaternion()
{

}

Quaternion & Quaternion::operator +(const Quaternion &q)
{
    return Quaternion(X + q.X, Y + q.Y, Z + q.Z, W + q.W);
}

Quaternion & Quaternion::operator +=(const Quaternion &q)
{
    *this = *this + q;
    return *this;
}

Quaternion & Quaternion::operator -(const Quaternion &q)
{
    return Quaternion(X - q.X, Y - q.Y, Z - q.Z, W - q.W);
}
Quaternion & Quaternion::operator -=(const Quaternion &q)
{
    *this = *this - q;
    return *this;
}

Quaternion & Quaternion::operator *(const Quaternion &q)
{
    return Quaternion(
        X * q.X - Y * q.Y - Z * q.Z - W * q.W,
        X * q.Y + Y * q.X - Z * q.W + W * q.Z,
        X * q.Z + Y * q.W + Z * q.X - W * q.Y,
        X * q.W - Y * q.Z + Z * q.Y + W * q.X
    );
}
Quaternion & Quaternion::operator *=(const Quaternion &q)
{   
    *this = *this * q;
    return *this;
}

Quaternion & Quaternion::operator /(const Quaternion &q)
{
    float square = q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W;
    return Quaternion(
        (X * q.X + Y * q.Y + Z * q.Z + W * q.W) / square,
        (X * q.Z - Y * q.X - Z * q.W + W * q.Z) / square,
        (X * q.Y + Y * q.W - Z * q.X - W * q.Y) / square,
        (X * q.W - Y * q.Z + Z * q.Y - W * q.X) / square
    );
}
Quaternion & Quaternion::operator /=(const Quaternion &q)
{
    *this = *this / q;
    return *this;
}

Quaternion & Quaternion::operator =(const Quaternion &q)
{
    X = q.X;
    Y = q.Y;
    Z = q.Z;
    W = q.W;
    return *this;
}

Quaternion & Quaternion::operator ^(int i)
{
    if(i ==0)
    {
        X = 1;
        Y = Z = W = 0;
    }
    else
        while(i > 1)
        {
            *this *= *this;
            i--;
        }
    return *this;
}


double Quaternion::Norm()
{
    return sqrt(X * X + Y * Y + Z * Z + W * W);
}

string Quaternion::ToString()
{
    string result;
    stringstream ss (stringstream::in | stringstream::out);
    ss<<X;
    if(Y>0)
        ss<<" + "<<Y<<" i";
    else  if(Y<0)
        ss<<" - "<<-Y<<" i";
    if(Z>0)
        ss<<" + "<<Z<<" j";
    else if(Z<0)
        ss<<" - "<<-Z<<" j";
    if(W>0)
        ss<<" + "<<W<<" k";
    else if(W<0)
        ss<<" - "<<-W<<" k";
    result = ss.str();
    return result;
}

program.cpp

#include <stdlib.h>
#include <iostream>
#include "quaternion.h"
#include <exception>
#include <windows.h>
#pragma comment(lib,"library")
#pragma comment(lib,"user32")
#pragma comment(lib,"kernel32")
using namespace std;

int main()
{
    try
    {
        cout<<"Quaternion class library unit test:\n";

        Quaternion p = Quaternion(1, 1, 1, 1);
        Quaternion q = Quaternion(10, 10, 10, 10);
        cout<<"q = "<<q.ToString()<<"\n";
        cout<<"p = "<<p.ToString()<<"\n";

        cout<<"testing *= operator:\n";
        q *= p;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"testing * operator:\n";
        q = q * p;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"testing /= operator:\n";
        q /= p;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"testing / operator:\n";
        q = q / p;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"testing += operator:\n";
        q += p;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"testing + operator:\n";
        q = q + p;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"testing -= operator:\n";
        q -= p;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"testing - operator:\n";
        q = q - p;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"testing = operator:\n";
        q = p;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"testing ^ operator:\n";
        cout<<"power 2:\n";
        q = q ^ 2;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"power 3:\n";
        q = q ^ 3;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"power 4:\n";
        q = q ^ 4;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"power 0:\n";
        q = q ^ 0;
        cout<<"q = "<<q.ToString()<<"\n";
        q = Quaternion(10, 10, 10, 10);

        cout<<"testing norm function:\n";
        cout<<"||q|| = "<<q.Norm()<<"\n";   
    }
    catch(...)
    {
        TCHAR errmsg[512];
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,0,::GetLastError(),0,errmsg,1024,NULL);
        cout<< "error!"<<errmsg;
    }
}

I didn't find any help in the msdn or the cl and link options. I hope any one can help.

here is a link to the current version http://jumbofiles.com/rh0j46ibyt56

Upvotes: 2

Views: 417

Answers (1)

jcoder
jcoder

Reputation: 30045

This isn't an answer to your problem but this code has a problem -

Quaternion & Quaternion::operator +(const Quaternion &q)
 {     
    return Quaternion(X + q.X, Y + q.Y, Z + q.Z, W + q.W); 
} 

you are creating an temporary object then returning a reference to it. By the time you use the reference in the caller, it will have been destructed. You need to not return a reference.

edit: And as pointed out below, this may corrupt your stack so could well be the cause of your problem.

Upvotes: 5

Related Questions