Toon posts:

[C++] DLLs maken

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik probeer een DLL te maken in Visual C++ om die vervolgens in Visual Basic te gebruiken. Ik ben begonnen met de standaard DLL uit de wizard.

Als VB code heb ik dit:
code:
1
2
3
4
5
6
Private Declare Function Verdubbel Lib "test.dll" Alias "?verdubbel@@YAHH@Z" (ByVal x As Integer) As Integer
Private Declare Function Test Lib "test.dll" Alias "?fnTest@@YAHXZ" () As Integer

Private Sub Form_Load()
  Form1.Text1.Text = Verdubbel(33)
End Sub


Als ik dit probeer uit te voeren krijg ik een "Bad DLL calling convention"

Het vreemde is, dat die Test functie wel werkt, dus ik dacht dat het aan de parameters moest liggen. Mijn functies (C++):

code:
1
2
3
4
5
6
7
TEST_API int fnTest(void) {
    return 42;
}

TEST_API int verdubbel(int x) {
    return x*2;
}


En verder staan de headers van deze functies nog in test.h.

Hoe los ik dit op?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:49
Heb je al uitgezocht welke calling convention Visual Basic gebruikt en C++ met de TEST_API specifier?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

het is overigens wat makkelijker als je een .DEF filetje aan je C++ project toevoegd, zodat je geen last krijgt van C++ name mangling (dus dat je functies namen krijgen als verdubbel@@YAHH@Z)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Soultaker schreef op 18 september 2002 @ 20:20:
Heb je al uitgezocht welke calling convention Visual Basic gebruikt en C++ met de TEST_API specifier?
Nee, euuh. :?

Ik zal eens MSDN gaan afspeuren.

Verwijderd

Topicstarter
.oisyn schreef op 18 september 2002 @ 20:25:
het is overigens wat makkelijker als je een .DEF filetje aan je C++ project toevoegd, zodat je geen last krijgt van C++ name mangling (dus dat je functies namen krijgen als verdubbel@@YAHH@Z)
Dat maakt verder niet uit toch? Het zou toch evengoed moeten werken?

Verwijderd

Topicstarter
1) Your program is calling a routine in a DLL that's being passed the wrong type of arguments.
Make sure all argument types agree with those specified in the declaration of the routine you are calling.

2) Your program is calling a routine in a DLL that's being passed the wrong number of arguments.
Make sure you are passing the same number of arguments indicated in the declaration of the routine you are calling.

3) Your program is calling a routine in a DLL, but isn't using the StdCall calling convention.
If the DLL routine expects arguments by value, then make sure ByVal is specified for those arguments in the declaration for the routine.

De derde kan het eigenlijk niet zijn, want de Test functie doet het wel. Het moet dus iets zijn met de parameters. Zouden de integers van VB niet hetzelfde zijn als de integers van C++?

Verwijderd

Een int in C in een Long in VB6. Die DEF file is trouwens wel belangrijk.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 18 september 2002 @ 20:27:
[...]


Dat maakt verder niet uit toch? Het zou toch evengoed moeten werken?


nee, maar het is maar net wat je lekker vind werken ;)

Oh, vergeet trouwens niet dat een Integer in VB 16 bits is, en dus overeen komt met het C++ type short (in MSVC dan)

Als je een C++ int door wil geven gebruik je het VB type Long :)

.edit: wat dev zei dus :Y)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:49
Verwijderd schreef op 18 september 2002 @ 20:30:
De derde kan het eigenlijk niet zijn, want de Test functie doet het wel. Het moet dus iets zijn met de parameters. Zouden de integers van VB niet hetzelfde zijn als de integers van C++?


Voor een functie zonder argumenten maakt de calling conventie minder uit (aangezien er toch geen argumenten opgeruimd hoeven worden), dus misschien gaat het juist wel daarom fout.

Als ik jou was, zou ik om te beginnen uitzoeken met wat voor calling convention je je functies exporteert. Daartoe moet je die TEST_API definitie even ontleden tot je bij __stdcall (waarschijnlijk) of iets dergelijks uitkomt.

Ik zou niet weten wat voor calling conventie Visual Basic gebruikt, maar ik neem aan dat je (net als in andere talen) wel kunt aangegeven wat voor calling conventie de geimporteerde functie gebruikt. Als je dat goed instelt, zou ik me niet kunnen voorstellen waar het nog mis gaat.

Passing by value lijkt me hier niet aan de orde, aangezien ik me niet kan voorstellen dat een integer by reference gepasst wordt in Visual Basic.

Modbreak: .oisynsorry dat ik je post editte, ik drukte op de verkeerde knop |:(
mijn excuses _/-\o_

[ Voor 0% gewijzigd door .oisyn op 18-09-2002 20:41 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

[nohtml]
Soultaker schreef op 18 september 2002 @ 20:35:
Passing by value lijkt me hier niet aan de orde, aangezien ik me niet kan voorstellen dat een integer by reference gepasst wordt in Visual Basic.
VB stuurt zijn parameters default door by reference. Dus tenzij je DLL functie een pointer naar int accepteert moet je m ByVal declareren

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • TheMrH
  • Registratie: April 2000
  • Laatst online: 22:45
Maak der es van:
code:
1
Private Declare Function Verdubbel Lib "test.dll" Alias "?verdubbel@@YAHH@Z" (ByVal x As Integer) As Long

The box said 'requires Windows 95 or better', so I installed Linux...


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:49
.oisyn schreef op 18 september 2002 @ 20:41:
VB stuurt zijn parameters default door by reference. Dus tenzij je DLL functie een pointer naar int accepteert moet je m ByVal declareren
Aha. Ik zag trouwens dat de topicstarter dat al gedaan had, dus daar zit 'm niet in. Moet je niet stiekum nog een STDCALL specificier oid erbij zetten stiekum? Ik kan het idee toch maar niet van me afzetten dat de foutmelding ergens op slaat. :)

btw: ga je nou m'n posts slopen omdat ik je naam verkeerd spelde? ;) :+

Modbreak: .oisynja :P
okee nou hou ik op ;) (mocht je nog iets willen editten dan geef je maar een gil :Y))

[ Voor 0% gewijzigd door .oisyn op 18-09-2002 20:46 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker schreef op 18 september 2002 @ 20:44:
[...]


Aha. Ik zag trouwens dat de topicstarter dat al gedaan had, dus daar zit 'm niet in. Moet je niet stiekum nog een STDCALL specificier oid erbij zetten stiekum?
VB doet DLL functies volgens mij stdcall... Als de DLL functies cdecl zijn dan kun je in VB de CDecl specifier gebruiken idd
Ik kan het idee toch maar niet van me afzetten dat de foutmelding ergens op slaat. :)
Waarschijnlijk op het feit dat een VB Integer 16 bits is ;)
btw: ga je nou m'n posts slopen omdat ik je naam verkeerd spelde? ;) :+


zie mijn edit in jouw post :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Soultaker schreef op 18 september 2002 @ 20:35:
Passing by value lijkt me hier niet aan de orde, aangezien ik me niet kan voorstellen dat een integer by reference gepasst wordt in Visual Basic.
Wat? Is het nu wel of niet by reference. Volgens mij niet.

Ik heb dit:

code:
1
2
3
4
5
#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif


Aargh! Ik snap het niet!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sjord: lees deze post nog even door ;)

Verder denk ik dat je naast die __declspec ook nog __stdcall moet gebruiken, of je moet je functie in VB declareren als CDecl

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Maak er in ieder geval stdcall van, en gebruik extern "C" voor de functies om name mangling te voorkomen:
code:
1
2
3
4
extern "C" TEST_API int __stdcall verdubbel(int x)
{
    return x*2;
}

edit: wel vreemd dat ie fnTest wel pakt. Het maakt voor een functie zonder parameters technisch gezien niet uit of het de C of stdcall convention gebruikt maar de naam blijft fout als het stdcall is (zou een underscore voor moeten en een @0 erachter). Bij verdubbel maakt het wel uit, waarschijnlijk stopt ie daarom pas bij die functie.

www.madwizard.org


Verwijderd

Topicstarter
Allemaal hardstikke bedankt, het werkt!

code:
1
2
3
4
5
6
7
8
Private Declare Function Verdubbel Lib "d:\sjoerd\development\test\release\test.dll" Alias "_verdubbel@4" (ByVal x As Long) As Long
Private Declare Function Test Lib "d:\sjoerd\development\test\release\test.dll" Alias "?fnTest@@YAHXZ" () As Integer

Private Sub Form_Load()
  Dim x As Long 'Dit hoeft mogelijk niet.
  x = 33#
  Form1.Text1.Text = Verdubbel(x)
End Sub


De truc zat inderdaad in de calling convention:
code:
1
extern "C" TEST_API int __stdcall verdubbel(int x)

Verwijderd

Topicstarter
Het werkt ook zonder Longs in VB, gewoon met Integers. Misschien niet helemaal betrouwbaar zodra je met getallen boven de 16 bits komt, maar toch. Dat was het probleem niet.

  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 21:46

johnwoo

3S-GTE

[mening]
Een .def file werkt zoo veel fijner dan die __declspec(dllexport) met de noodzaak van function decorations in VB...
[/mening]

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

johnwoo: idd, dat vind ik dus ook
plus dat je gewoon makkelijk kunt zien welke functies nou geexport worden en welke niet... scheelt weer door je code heen spitten :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 21:46

johnwoo

3S-GTE

.oisyn schreef op 18 september 2002 @ 23:13:
johnwoo: idd, dat vind ik dus ook
plus dat je gewoon makkelijk kunt zien welke functies nou geexport worden en welke niet... scheelt weer door je code heen spitten :)
... en je mag zelf de ordinals van je functies bepalen... yay 8)

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1

Pagina: 1