Springen naar inhoud

Probleem met linken van een dll


  • Log in om te kunnen reageren

#1

Stef31

    Stef31


  • >250 berichten
  • 609 berichten
  • Ervaren gebruiker

Geplaatst op 17 januari 2008 - 23:14

Hallo programmeurs,

Ik heb een Visual C++ programma geschreven met inline assembler.
Ik kan een DLL wel maken maar wanneer mijn hoofdprogramma die DLL wilt gebruiken loopt het verkeerd.
Ik denk eerder dat die dll misschien ook een fout vertoond

Hier in bijlage mijn ganse code

Math32.h

extern "C" __declspec(dllexport) double __stdcall SinH(double x);
extern "C" __declspec(dllexport) double __stdcall CosH(double x);
extern "C" __declspec(dllexport) double __stdcall TanH(double x);

extern "C" __declspec(dllexport) double __stdcall SinX(double x);
extern "C" __declspec(dllexport) double __stdcall CosX(double x);
extern "C" __declspec(dllexport) double __stdcall TanX(double x);
extern "C" __declspec(dllexport) double __stdcall CotTan(double x);
extern "C" __declspec(dllexport) double __stdcall CosSecan(double x);
extern "C" __declspec(dllexport) double __stdcall SecCan(double x);

extern "C" __declspec(dllexport) double __stdcall ArcSin(double x);
extern "C" __declspec(dllexport) double __stdcall ArcCos(double x);
extern "C" __declspec(dllexport) double __stdcall ArcCot(double x);
extern "C" __declspec(dllexport) double __stdcall ArcCsc(double x);
extern "C" __declspec(dllexport) double __stdcall ArcSec(double x);

extern "C" __declspec(dllexport) double __stdcall Exp2(double x);
extern "C" __declspec(dllexport) double __stdcall Exp10(double x);
extern "C" __declspec(dllexport) double __stdcall PowXY(double x, double y);
extern "C" __declspec(dllexport) double __stdcall ExpX(double x);
extern "C" __declspec(dllexport) double __stdcall Log10(double x);
extern "C" __declspec(dllexport) double __stdcall Ln(double x);
int MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);

Math32.cpp

// Math32.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call,LPVOID lpReserved)
{
	MessageBoxA(0, "Copyright (2007) Stephane Fonteyne", "Math32.dll", MB_APPLMODAL | MB_ICONINFORMATION | MB_OKCANCEL);
   	return TRUE;
}

// =======================================================================
//							Trigometrische Functies
// =======================================================================
extern "C" __declspec(dllexport) double __stdcall SinH(double x)
{
	double	temp = 1.0;

	_asm
	{
		FLD x
		FST ST(1)		;ST1=x
		F2XM1
		FLD1
		FADD
		FST ST(2)		;ST2=x^2
		FLDL2E
		FLD1
		FSUB
		FLD ST(2)
		FMUL
		F2XM1
		FLD1
		FADD
		FLD ST(1)
		FMUL			  ;ST=2^x*2^(0.44*x)
		FST ST(1)
		FLD1
		FDIVR			 ;ST=1/(2^x*2^(0.44*x))
		FLD ST(1)
		FSUBR
		FSTP ST(1)
		FLD1
		FLD1
		FADD
		FLD ST(1)
		FDIVR
		FST temp
		FNINIT
	}
		return(temp);
}

extern "C" __declspec(dllexport) double __stdcall CosH(double x)
{
	double temp = 1.0;

	_asm
	{
		FLD x
		FST ST(1)		;ST1=L
		F2XM1
		FLD1
		FADD
		FST ST(2)		;ST2=L^2
		FLDL2E
		FLD1
		FSUB
		FLD ST(2)
		FMUL
		F2XM1
		FLD1
		FADD
		FLD ST(1)
		FMUL			 ;ST=2^L*2^(0.44*L)
		FST ST(1)
		FLD1
		FDIVR			;ST=1/(2^L*2^(0.44*L))
		FLD ST(1)
		FADD		 
		FSTP ST(1)
		FLD1
		FLD1
		FADD
		FLD ST(1)
		FDIVR
		FST temp
		FNINIT
	}
	return(temp);
}

extern "C" __declspec(dllexport) double __stdcall TanH(double x)
{
	double MCX = 0.0;
	double MSX = 0.0;
	double temp = 0.0;

	
	MCX = CosH(x);
	MSX = SinH(x);
	_asm
	{
		FLD MCX
		FLD MSX
		FDIVR
		FST temp
		FNINIT
	}
	return(temp);
}

extern "C" __declspec(dllexport) double __stdcall SinX(double x)
{
	double temp = 0.0;

	_asm
	{
		FLD x	; laad argument x op TOS
		FSIN	; bereken de Sin(x)
		FST temp; sla de terugkeerwaarde op op de TOS
		FNINIT			
	}
	return(temp);
}

extern "C" __declspec(dllexport) double __stdcall CosX(double x)
{
	double temp = 0.0;

	_asm
	{
		FLD x	; laad argument x op TOS
		FCOS	; bereken de Cos(x)
		FST temp; sla de terugkeerwaarde op op de TOS
		FNINIT
	}
	return(temp);
}

extern "C" __declspec(dllexport) double __stdcall TanX(double x)
{
	double temp = 0.0;

	_asm
	{
		FLD x	; sla de terugkeerwaarde op op de TOS
		FPTAN	; bereken de Tan(x)
		FST temp; sla de terugkeerwaarde op op de TOS
		FNINIT
	}
	return(temp);
}

// ====================================================================
// Berekend de cotangens van de ST(0) en zet het resultaat in de ST(0)
// ST(0) bevat de invoerwaarde x (in radialen) en moet liggen tussen 
// -2^63 en +2^63
// Zorg ervoor dat we één vrij register hebben op de stack om de functie
// zonder problemen uit te voeren
// cot(x) = 1 / tan(x)
// ====================================================================
extern "C" __declspec(dllexport) double __stdcall CotTan(double x)
{
	double temp = 0.0;

	_asm
	{	
		FLD x				
		FSINCOS
		FDIVR
		FST temp
		FNINIT
	}
	return(temp);
}

// ====================================================================
// Berekend de cosSecan van de ST(0) en zet het resultaat in de ST(0)
// ST(0) bevat de invoerwaarde x (in radialen) en moet liggen tussen 
// -2^63 en +2^63
// De CosSecan van de waarde x is niet gedefinieerd voor elke waarde van
// de sin(x) dat de waarde 0 geeft
// Zorg ervoor dat we één vrij register hebben op de stack om de functie
// zonder problemen uit te voeren
// cot(x) = 1 / tan(x)
// ====================================================================
extern "C" __declspec(dllexport) double __stdcall CosSecan(double x)
{
	double temp = 0.0;

	_asm
	{
		FLD x
		FSIN
		FLD1
		FDIVR
		FST temp
		FNINIT
	}
	return(temp);
}

// ====================================================================
// Berekend de SecCan van de ST(0) en zet het resultaat in de ST(0)
// ST(0) bevat de invoerwaarde x (in radialen) en moet liggen tussen 
// -2^63 en +2^63
// De CosSecan van de waarde x is niet gedefinieerd voor elke waarde van
// de sin(x) dat de waarde 0 geeft
// Zorg ervoor dat we één vrij register hebben op de stack om de functie
// zonder problemen uit te voeren
// sec(x) = 1 / cos(x)
// ====================================================================
extern "C" __declspec(dllexport) double __stdcall SecCan(double x)
{
	double temp = 0.0;
	_asm
	{
		FLD x
		FCOS
		FLD1
		FDIVR
		FST temp
		FNINIT
	}
	return(temp);
}

//========================================================================
// Berekend de boogsinus van de ST(0) en plaatst het resultaat in de ST(0)
// Beschikbaar bereik is : -1 <= x <= +1
// ArcSin(x) = Atan(Sqrt(x * x / (1 - x * x)))
//========================================================================
extern "C" __declspec(dllexport) double __stdcall ArcSin(double x)
{
	double temp = 0.0;
	_asm
	{
		FLD x
		FMUL				; berekend x * x
		FLD ST(0)			; x * x op de TOS
		FLD1				; bereken 1 - x^2
		FSUBR

		FDIV				; bereken x^2 / (1 - x^2)
		FSQRT				; bereken sqrt(x^2) / (1 - x^2)
		FLD1				; bereken de ArcTan
		FPATAN
		FST temp			; opslaan in de temp
		FNINIT
	}
	return(temp);
}

//========================================================================
// Berekend de boogcosinus van de ST(0) en plaatst het resultaat in de ST(0)
// Beschikbaar bereik is : -1 <= x <= +1
// ArcCos(x) = Atan(Sqrt(1 - x * x / ( x * x)))
//========================================================================
extern "C" __declspec(dllexport) double __stdcall ArcCos(double x)
{
	double temp = 0.0;
	_asm
	{
		FLD x
		FMUL				; berekend x * x
		FLD ST(0)			; x * x op de TOS
		FLD1				; bereken 1 - x^2
		FSUBR

		FDIVR				; bereken (1 - x^2) / (x^2)
		FSQRT				; bereken sqrt(1 - x^2) / (x^2)
		FLD1				; bereken de ArcTan
		FPATAN
		FST temp			; opslaan in de temp
		FNINIT
	}
	return(temp);
}

//========================================================================
// Berekend de boogcotan van de ST(0) en plaatst het resultaat in de ST(0)
// x kan geen 0 worden
// ArcCot(x) = Atan(1/x)
//========================================================================
extern "C" __declspec(dllexport) double __stdcall ArcCot(double x)
{
	double temp = 0.0;
	_asm
	{
		FLD x
		FLD1				; bereken fpTan
		FXCH				; ATan(ST(1) / ST(0)
		FPTAN				; ATan(ST(0) / ST(1)
		FST temp			; opslaan in de temp
		FNINIT
	}
	return(temp);
}

//========================================================================
// Berekend de boogCosSecant van de ST(0) en plaatst het resultaat in de 
// ST(0)
// Absolute waarde van x abs(x) moet groter zijn dan 1
// ArcCsc(x) = ATan(sqrt(1 / (x * x - 1)))
//========================================================================
extern "C" __declspec(dllexport) double __stdcall ArcCsc(double x)
{
	double temp = 0.0;
	_asm
	{
		FLD	x				; ophalen van waarde x
		FMUL				; bereken x * x
		FLD1				; bereken (x * x) - 1
		FSUB				;
		FLD1				; bereken 1 / (x * x) - 1
		FDIVR				;
		FSQRT				; bereken sqrt((x * x) - 1))
		FLD1				;
		FPATAN				; bereken de arctan(sqrt(x * x) - 1)))
		FST temp			; opslaan in geheugenplaats
		FNINIT
	}
	return(temp);
}

//========================================================================
// Berekend de boogSecan van de ST(0) en plaatst het resultaat in de ST(0)
// Absolute waarde van x abs(x) moet groter zijn dan 1
// ArcSec(x) = ATan(sqrt(x * x - 1))
//========================================================================
extern "C" __declspec(dllexport) double __stdcall ArcSec(double x)
{
	double temp = 0.0;
	_asm
	{
		FLD	x				; ophalen van waarde x
		FMUL				; bereken x * x
		FLD1				; bereken (x * x) - 1
		FSUB				;
		FSQRT				; bereken sqrt((x * x) - 1))
		FLD1				;
		FPATAN				; bereken de arctan(sqrt(x * x) - 1)))
		FST temp			; opslaan in geheugenplaats
		FNINIT
	}
	return(temp);
}

//=======================================================================
//						Mathematic Functions
//=======================================================================

//=========================================================================
// Berekend 2^x
// 2^x = 2 ^ int(x) * 2 ^ frac(x)
// We bereken 2 ^ int(x) met de FPU functie FSCALE
// We bereken 2 ^ frac(x) met de FPU functie F2XM1
// We gebruiken 3 vrije registers ST(0), ST(1), ST(2)
//=========================================================================
extern "C" __declspec(dllexport) double __stdcall Exp2(double x)
{
	double temp = 0.0;
	short MaskedCW;
	short SaveCW;
	_asm
	{
		FLD x					; waarde van x ophalen
		FSTCW MaskedCW			; 
		OR BYTE PTR MaskedCW + 1, 1100b;
		FLDCW MaskedCW
		FLD ST(0)
		FLD ST(0)						
		FRNDINT					; bereken gehele deel
		FXCH					; verwissel de int waarden
		FSUB ST(0), ST(1)		; bereken frac deel
		F2XM1					; bereken 2 ^ frac(x) - 1
		FLD1
		FADD					; bereken 2 ^ frac(x)
		FXCH					; Ophalen van het gehele deel
		FLD1					; bereken 1 * 2 ^ int(x)
		FSCALE
		FSTP ST(1)				; haal de waarde van de stack ST(1) op
		FMUL					; bereken 2 ^ int(x) * 2 ^ frac(x)
		FLDCW SaveCW			; herstel de afrondingsmode
		FST temp
		FNINIT
	}
	return(temp);
}

//=========================================================================
// Berekend Exp10(x)
// Exp10(x) = 2 ^ (x * log(10))
// We gebruiken 3 vrije registers ST(0), ST(1), ST(2)
//=========================================================================
extern "C" __declspec(dllexport) double __stdcall Exp10(double x)
{
	double temp;
	_asm
	{
		FLD x					; waarde van x ophalen
		FLDL2T					; zet de Log(10) op de stack
		FMUL					; berekend x * Log(10)
		CALL Exp2				; berekend 2 ^ x * Log(10)
		FST temp
		FNINIT
	}
	return(temp);
}

//===========================================================================
// Berekend PowXY(x,y)
// Bereken van PowXY(x,y) = 2 ^ (x * log(y))
// y = ST(1), x = ST(0)
// We gebruiken 3 vrije stack registers
// eis : y > 0
//===========================================================================
extern "C" __declspec(dllexport) double __stdcall PowXY(double x, double y)
{
	double temp = 0.0;

	_asm
	{
		FLD x				; x ophalen en in ST(0)
		FLD y				; y ophalen en in TOS zetten
		FXCH				; bereken Log(y)
		FLD1
		FXCH
		FYL2X
		FMUL				; bereken x * log(y)
		CALL Exp2			; bereken 2 ^ (x * log(y))
		FST temp
		FNINIT
	}
	return(temp);
}

//==========================================================================
// Berekend ExpX(x)
// ExpX(x) = 2 ^ (x * Log(e)
// We gebruiken 3 vrije registers ST(0), ST(1), ST(2)
//==========================================================================
extern "C" __declspec(dllexport) double __stdcall ExpX(double x)
{
	double temp;
	_asm
	{
		FST x
		FLDL2E
		FMUL
		CALL Exp2
		FST temp
		FNINIT
	}
	return(temp);
}

//===========================================================================
// Berekend de Log10(x) functie van de waarde x
// Bereik van de getallen : x moet positief zijn
// Log(x) = Lg(x) / lg(10)
//===========================================================================
extern "C" __declspec(dllexport) double __stdcall Log10(double x)
{
	double temp = 0.0;
	_asm
	{
		FLD x
		FLD1
		FXCH						
		FYL2X				; bereken 1 * lg(x)
		FLDL2T				; haal de functie lg(10) op
		FDIV				; bereken lg(x) / lg(10)
		FST	temp
		FNINIT
	}
	return(temp);
}

//============================================================================
// Berekend de neperiaanse logaritme met basis e macht van de waarde x
// x moet groter zijn dan 0
// Ln(x) = lg(x) / lg(e)
//============================================================================
extern "C" __declspec(dllexport) double __stdcall Ln(double x)
{
	double temp = 0.0;
	_asm
	{
		FLD x
		FLD1
		FXCH
		FYL2X
		FLDL2E
		FDIV
		FST temp
		FNINIT
	}
	return(temp);
}

//============================================================================
// Berekenen van de n de machtswortel van x en y
// Aanroepen : call powxy(x,y)
// x ^ (y / n) = powxy(x, y/n)
// result => ST(0)
// x => ST(1)
// y => ST(2)
//============================================================================

Math32App1.cpp
// Hier mijn hoofdprogramma waar de DLL niet kan worden gelinkt
#include "Math32.h"// MathApp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;

// #include "C:\Math32.h"

int _tmain(int argc, _TCHAR* argv[])
{
	// ====================================================================
	//						Zet dit in een header file
	// define prototype of function pointer to DLL function
	typedef INT (CALLBACK* LPFNDLLFUNC2)(INT, INT);
	typedef INT (CALLBACK* LPFNDLLFUNC1)(INT);
	// ====================================================================

	// Met dit gaat het verkeerd !
	// Hoe kan je dat dan doen als je met doubles wilt werken?
	// Staat nergens uitgelegd in boeken van WinAPI
	// typedef DOUBLE (CALLBACK* LPFNDLLFUNC2)(DOUBLE, DOUBLE);
	// typedef DOUBLE (CALLBACK* LPFNDLLFUNC1)(DOUBLE);
	
	// Windows Handle to DLL
	HINSTANCE hinstance_DLL_Library;
	
	// Function pointers to DLL functions
	LPFNDLLFUNC1 lpfnDLLSinH;
	LPFNDLLFUNC1 lpfnDLLCosH;
	LPFNDLLFUNC1 lpfnDLLTanH;
	LPFNDLLFUNC1 lpfnDLLSinX;
	LPFNDLLFUNC1 lpfnDLLCosX;
	LPFNDLLFUNC1 lpfnDLLTanX;
	LPFNDLLFUNC1 lpfnDLLCotan;
	LPFNDLLFUNC1 lpfnDLLCosSecan;
	LPFNDLLFUNC1 lpfnDLLSecan;
	LPFNDLLFUNC1 lpfnDLLArcSin;
	LPFNDLLFUNC1 lpfnDLLArcCos;
	LPFNDLLFUNC1 lpfnDLLArcCot;
	LPFNDLLFUNC1 lpfnDLLArcCsc;
	LPFNDLLFUNC1 lpfnDLLArcSec;
	LPFNDLLFUNC1 lpfnDLLExp2;
	LPFNDLLFUNC1 lpfnDLLExp10;
	LPFNDLLFUNC2 lpfnDLLPowXY;
	LPFNDLLFUNC1 lpfnDLLExpX;
	LPFNDLLFUNC1 lpfnDLLLog10;
	LPFNDLLFUNC1 lpfnDLLLn;
	
	// Is Run Time Linking Successfull?
	BOOL fRunTimeLinkSuccess = FALSE;

	// Variables for function Result & Function Parameters
	double iReturnValue;

	cout << "\n\nLinking between Unmanaged VC++ project and DLL\n\n";

	// Get handle to the DLL module => refer to local project directory
	hinstance_DLL_Library = LoadLibrary("Math32");
	
	// If the handle is valid, try to get the function address
	if(hinstance_DLL_Library != NULL)
	{
		// Report valid handle
		cout << "\n Math32.dll found !\n";
	
		// Trace name of DLL function in Math32.exp
		// _SinX@8 bvb : 8 bytes gereserveerd voor SP
		// 8 = 2 * 4 bytes = 2 * 32 bit double

		// Get the address of de DLL functions
		lpfnDLLSinH		= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_SinH@8");
		lpfnDLLCosH		= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_CosH@8");
		lpfnDLLTanH		= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_TanH@8");
		lpfnDLLSinX		= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_SinX@8");
		lpfnDLLCosX		= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_CosX@8");
		lpfnDLLTanX		= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_TanX@8");
		lpfnDLLCotan	= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_CotanH@8");
		lpfnDLLCosSecan	= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_CosSecan@8");
		lpfnDLLSecan	= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_Secan@8");
		lpfnDLLArcSin	= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_ArcSin@8");
		lpfnDLLArcCos	= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_ArcCos@8");
		lpfnDLLArcCot	= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_ArcCot@8");
		lpfnDLLArcCsc	= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_ArcCsc@8");
		lpfnDLLArcSec	= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_ArcSec@8");
		lpfnDLLExp2		= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_Exp2@8");
		lpfnDLLExp10	= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_Exp10@8");
		lpfnDLLPowXY	= (LPFNDLLFUNC2) GetProcAddress(hinstance_DLL_Library, "_PowXY@8");
		lpfnDLLExpX		= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_ExpX@8");
		lpfnDLLLog10	= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_Log10@8");
		lpfnDLLLn		= (LPFNDLLFUNC1) GetProcAddress(hinstance_DLL_Library, "_Ln@8");


		// If the function pointer is invalid, unload DLL from memory
		if(!lpfnDLLSinH)
		{
			// handle the error
			FreeLibrary(hinstance_DLL_Library);
			return -1;
		}
		
		// ===========================================================================
		//							Einde van de definities en declaraties
		// ===========================================================================

		// ===========================================================================
		//							Start van het programma
		// ===========================================================================
		// else call the function
		// Hier gaan we de functie gebruiken
		{
			// RunTime linking with the Math32.dll function
			// is successfull !
			fRunTimeLinkSuccess = TRUE;
			cout << "\nDLL function <SinH(x)> found in Math32.dll";
			double x = 34.546;
			iReturnValue = lpfnDLLSinH(x);
			cout << "De SinH van " << x << " is gelijk aan " << iReturnValue << " rad.";
			cin.get();
		}
	}
	return 0;
}

Hier gaat het dus mis:

Krijg de volgende error:
================

Hij vind mijn DLL niet zegt hij en de functie ook niet wat gaat hier fout weet het nog steeds niet heb nochtans alles juist gedaan.
De commentaar staat in mijn code wat hij niet doet

Mijn vraag is het volgende:

1.) Hoe kan ik mijn DLL en hoofdprogramma laten toegang krijgen om met DOUBLE als argumenten en returnwaarde te laten werken want dat gaat niet daar heb ik al dagen achter gezocht maar ik vind het gewoon niet

Kan iemand mij helpen dat ik die DLL wel kan linken in mijn hoofdprogramma

Bijlage  Project_met_DLL.zip   640,68K   28 maal gedownload

Veranderd door Stef31, 17 januari 2008 - 23:16


Dit forum kan gratis blijven vanwege banners als deze. Door te registeren zal de onderstaande banner overigens verdwijnen.




0 gebruiker(s) lezen dit onderwerp

0 leden, 0 bezoekers, 0 anonieme gebruikers

Ook adverteren op onze website? Lees hier meer!

Gesponsorde vacatures

Vacatures