1 van 1

Probleem met linken van een dll

Geplaatst: do 17 jan 2008, 23:14
door Stef31
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

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);
Math32.cpp

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)

//============================================================================
Math32App1.cpp

// 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;

}
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
Project_met_DLL
(640.68 KiB) 143 keer gedownload