Basic DLL aanroepen vanuit C

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik probeer een library die geschreven is in FreeBasic te gebruiken in mijn C library. Nu heb ik van de basic library echter alleen een .DLL bestand (geen .lib) dus volgens mij moet ik deze in runtime linken. De code die ik hiervoor probeer te gebruiken is (alleen relevante code):
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
HINSTANCE hinstXSteamLib ;

// DLL function signature
typedef double (*importFunction)(double);

LRESULT Tsat_pFunction(  LPCOMPLEXSCALAR     b,  //put return value here
                         LPCCOMPLEXSCALAR    a   )   // 1st argument
{
    importFunction Tsat_p ;

    // Load DLL file
    HINSTANCE hinstXSteamLib = LoadLibrary(TEXT("XSteam_V2.6b.dll"));
    if (hinstXSteamLib == NULL)
    {
        //ERROR: unable to load DLL
        return 1; //report error to mathcad
    }
    
    // Get function pointer
    Tsat_p = (importFunction) GetProcAddress(hinstXSteamLib, "Tsat_p@8");
    if (Tsat_p == NULL)
    {
        //ERROR: unable to find DLL function
        FreeLibrary(hinstXSteamLib);
        return 1; //report error to mathcad
    }
    
    // Call function.
    b->real = Tsat_p( a->real );

    FreeLibrary(hinstXSteamLib);
    return 0; //success
}


De functiedefinietie in freebasic ziet er als volgt uit:
Visual Basic:
1
Function Tsat_p StdCall Alias "Tsat_p" (ByVal p As Double) As Double EXPORT


Nu is de foutmelding die ik krijg:
'Poging tot het lezen of schrijven van beveiligd geheugen'.

Kan iemand me uitleggen waarom ik geen toegang heb tot de dll? Of misschien uitleggen wat ik verkeerd doe. Ik moet eerlijk toegeven dat ik (nog) niet heel veel verstand heb van pointers naar geheugenadressen etc. Ik begrijp ook niet waarom ik Tsat_p@8 moet gebruiken (waarom die @8? als ik dit niet doe wil hij de pointer naar de functie al niet eens laden. Volgens mij heeft het te maken dat het argument van de functie een double is, 8 bytes dus).

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Opgelost, de typedef moest zijn:
typedef double (CALLBACK* importFunction)( double );
en dan de pointer aanroepen, ofzo:
b->real = (*Tsat_p)( a->real );

Ik begrijp niet helemaal wat ik aan het doen ben, maar het werkt in elk geval :)

[ Voor 47% gewijzigd door Verwijderd op 27-03-2010 18:12 ]


Acties:
  • 0 Henk 'm!

  • user109731
  • Registratie: Maart 2004
  • Niet online
Verwijderd schreef op zaterdag 27 maart 2010 @ 18:11:
Ik begrijp niet helemaal wat ik aan het doen ben, maar het werkt in elk geval :)
C:
1
b->real = (*Tsat_p)( a->real );

Dit is volgens mij hetzelfde als:
C:
1
b->real = Tsat_p(a->real);

Dan is het enige verschil nog de CALLBACK die je hebt toegevoegd:
C:
1
typedef double (CALLBACK* importFunction)( double );

Waarschijnlijk is CALLBACK een define met de calling convention. De calling convention bepaald o.a. hoe argumenten aan een functie worden doorgegeven, in welk register de return value staat, etc. Ik gok dat de C-compiler cdecl gebruikt en je DLL stdcall en dat veroorzaakte crashes :)
edit:
Verwijderd schreef op zaterdag 27 maart 2010 @ 16:31:
Ik begrijp ook niet waarom ik Tsat_p@8 moet gebruiken (waarom die @8? als ik dit niet doe wil hij de pointer naar de functie al niet eens laden. Volgens mij heeft het te maken dat het argument van de functie een double is, 8 bytes dus).
Dat heet name mangling. Tsat_p@8 is een functie met stdcall calling convention en 8 bytes aan argumenten.

[ Voor 62% gewijzigd door user109731 op 27-03-2010 19:36 ]