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
Code: Selecteer alles
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);
Code: Selecteer alles
// 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)
//============================================================================
// Hier mijn hoofdprogramma waar de DLL niet kan worden gelinkt
Code: Selecteer alles
#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;
}
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