[c++/dll] functie aanroep in DLL van een externe c-file

Pagina: 1
Acties:

  • Boy
  • Registratie: November 2001
  • Laatst online: 10:05

Boy

www.byoscoop.nl

Topicstarter
Het volgende deze keer het geval, ik vind nergens een oplossing op internet/GoT, maar het moet toch wel gebruikt worden.

Ik heb een DLL, maar hierin worden functies gebruikt die in een externe C-file zitten. Deze c-file moet je dus wel altijd bij de DLL hebben (Even niet erover hebben van waarom doe je 'm dan niet meebuilden in de DLL?').

Nu krijg ik natuurlijk allemaal unresolved symbols. Hoe kan ik 'm zeggen dat deze functie definities in een andere c-file te vinden zijn buiten de dll?

Ik werk trouwens met Visual C++.

[ Voor 6% gewijzigd door Boy op 08-08-2005 11:20 ]

Naar de bioscoop? => gebruik de app op Byoscoop.nl


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:47

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik snap er niets van :P
Een C file die je bij de DLL moet hebben? Hoe moet ik me dat voorstellen dan? Gebruikt de DLL die functies die in de C file staan? En zo ja, hoe moet dat in hemelsnaam gaan werken?

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.


  • Boy
  • Registratie: November 2001
  • Laatst online: 10:05

Boy

www.byoscoop.nl

Topicstarter
.oisyn schreef op maandag 08 augustus 2005 @ 11:23:
Ik snap er niets van :P
Een C file die je bij de DLL moet hebben? Hoe moet ik me dat voorstellen dan? Gebruikt de DLL die functies die in de C file staan? En zo ja, hoe moet dat in hemelsnaam gaan werken?
Nou, zeg ik heb een functie logGegevens(CString a_iets);

die logGegevens staat in een C-file. Ik include wel de header mee in de DLL, maar niet die C-file. Hij weet de declaratie, maar vind natuurlijk vervolgens niet de definitie bij het compileren van de DLL.

Het logging gedeelte staat los van de DLL, maar maakt (nu nog) gebruik ervan. Het is eigenlijk een tijdelijke oplossing die ik zoek. Ik moet nog voorstellen bij m'n baas om het te scheiden (die is er even niet, vakantie).

Dus die dll gebruik ik in een programma en bij het compileren van dat programma wordt de logfile (c-file) wel geinclude.

edit:

Bij het compileren wil ik dus tegen de DLL zeggen: ja, ik weet dat je nog niet weet hoe je LogGegevens moet oplossen, maar dat is wel bekend wanneer je gebruikt wordt in een voor jou bestemd programma. Vind je het dan nog niet, kom dan maar met unresolved symbols.

[ Voor 14% gewijzigd door Boy op 08-08-2005 11:30 ]

Naar de bioscoop? => gebruik de app op Byoscoop.nl


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

het is trouwens nog steeds onduidelijk met welke versie van Visual C++ je werkt: 6, .NET 2003, .NET 2005 beta ???

je zal de functie uit de DLL moeten importeren. decl spec import (zo herinner ik me hem altijd, maar hoe de syntax er precies uitziet google je even voor) zo kun je die functie dus uit de DLL halen.

ASSUME makes an ASS out of U and ME


  • Boy
  • Registratie: November 2001
  • Laatst online: 10:05

Boy

www.byoscoop.nl

Topicstarter
Ik begrijp volgens mij wat ik verkeerd denk.

die dll moet gewoon alles erin hebben. Wat ik wil, kan wel met een .lib, niet een dll.

Maar je krijgt een .lib bij die DLL, die gebruik ik in het andere programma. Is er echt geen mogelijkheid voor hetgene wat ik wil?

Naar de bioscoop? => gebruik de app op Byoscoop.nl


  • Boy
  • Registratie: November 2001
  • Laatst online: 10:05

Boy

www.byoscoop.nl

Topicstarter
HIGHGuY schreef op maandag 08 augustus 2005 @ 11:36:
het is trouwens nog steeds onduidelijk met welke versie van Visual C++ je werkt: 6, .NET 2003, .NET 2005 beta ???

je zal de functie uit de DLL moeten importeren. decl spec import (zo herinner ik me hem altijd, maar hoe de syntax er precies uitziet google je even voor) zo kun je die functie dus uit de DLL halen.
Ik werk met VC++ 6.

Kan ik dan gewoon zeggen 'die functie moet je importeren, dat zie je later wel'? (ja, ik praat altijd tegen m'n dll's ;) )

Want hij weet niet waar die c-file is...

[edit]
Ik moet um niet UIT de DLL halen, maar later moet de DLL weten waar hij 'm moet vinden...

[ Voor 10% gewijzigd door Boy op 08-08-2005 11:49 ]

Naar de bioscoop? => gebruik de app op Byoscoop.nl


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:47

.oisyn

Moderator Devschuur®

Demotivational Speaker

Boy schreef op maandag 08 augustus 2005 @ 11:28:
Dus die dll gebruik ik in een programma en bij het compileren van dat programma wordt de logfile (c-file) wel geinclude.

edit:

Bij het compileren wil ik dus tegen de DLL zeggen: ja, ik weet dat je nog niet weet hoe je LogGegevens moet oplossen, maar dat is wel bekend wanneer je gebruikt wordt in een voor jou bestemd programma. Vind je het dan nog niet, kom dan maar met unresolved symbols.
Aha, je wilt dus dat de applicatie die de DLL gebruikt de logfunctie export, zodat de DLL deze functie kan importeren. Dat kan wel, maar het punt is alleen dat je bij het builden van DLL al informatie nodig hebt over in welke andere DLL die functie zit, oftewel in je uiteindelijke executable. Wat je dan moet doen is de functie meecompileren als dllexport in je executable, de linker zal dan naast je executable ook een .lib genereren. Vervolgens kun je de dll bouwen met die functie als dllimport, en kun je linken tegen de lib van je executable.

Het nadeel hiervan is dat je je executable zelf niet kunt linken tegen de .lib van je dll (die heb je immers nog niet gebouwd), en dat je dll altijd afhankelijk is van je executable. Het is wellicht handiger om gewoon een tweede DLL te maken waar alleen die logfunctie in zit.

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.


  • Boy
  • Registratie: November 2001
  • Laatst online: 10:05

Boy

www.byoscoop.nl

Topicstarter
.oisyn schreef op maandag 08 augustus 2005 @ 11:58:
[...]


Aha, je wilt dus dat de applicatie die de DLL gebruikt de logfunctie export, zodat de DLL deze functie kan importeren. Dat kan wel, maar het punt is alleen dat je bij het builden van DLL al informatie nodig hebt over in welke andere DLL die functie zit, oftewel in je uiteindelijke executable. Wat je dan moet doen is de functie meecompileren als dllexport in je executable, de linker zal dan naast je executable ook een .lib genereren. Vervolgens kun je de dll bouwen met die functie als dllimport, en kun je linken tegen de lib van je executable.

Het nadeel hiervan is dat je je executable zelf niet kunt linken tegen de .lib van je dll (die heb je immers nog niet gebouwd), en dat je dll altijd afhankelijk is van je executable. Het is wellicht handiger om gewoon een tweede DLL te maken waar alleen die logfunctie in zit.
Ik begrijp het volgens mij wel wat je bedoelt. Die afhankelijkheid van de DLL aan die specifieke .exe wordt dan wel erg groot.

edit:

En die tweede DLL erbij bouwen vind ik ook weer best jammer met alleen die logfunctie erin. Of daar kan ik gewoon een .lib van maken (geen dll natuurlijk)


Wat ik wil is dat die log.c file open blijft voor de gebruiker van de dll. Hij moet die ook zo kunnen aanpassen. Geen afhankelijkheid van de DLL aan die c-file. (op dit moment ben ik even de gebruiker, maar het wordt ook (later) in andere programma's gebruikt).

Er zijn nog meerdere libraries, maar dit zijn gewoon .lib files zonder DLL's. Daar gaat dat dus wel gewoon mee omdat het linken gebeurt tijdens het bouwen van de applicatie die er gebruik van maakt. Ik maak gebruik van een DLL omdat ik ook dialogs in de library wil hebben (dat was vrijwel niet te doen in een .lib merkte ik, met dll lukte het me wel).

die andere .lib files worden ook meegelinkt in de dll. Die maken ook weer gebruik van die log.c file, dus die beginnen ook te klagen als ik 'm niet in het DLL project erbij heb staan als ik de dll compile.

[ Voor 5% gewijzigd door Boy op 08-08-2005 12:10 ]

Naar de bioscoop? => gebruik de app op Byoscoop.nl


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:47

.oisyn

Moderator Devschuur®

Demotivational Speaker

Boy schreef op maandag 08 augustus 2005 @ 12:09:
Wat ik wil is dat die log.c file open blijft voor de gebruiker van de dll. Hij moet die ook zo kunnen aanpassen. Geen afhankelijkheid van de DLL aan die c-file. (op dit moment ben ik even de gebruiker, maar het wordt ook (later) in andere programma's gebruikt).
Zo te horen wil jij gewoon een OO interface die je aan je DLL functies mee kunt geven, en die DLL roept gewoon weer (virtual) methods op dat object aan. Op die manier kan iedereen z'n eigen logger implementeren, en zou je evt. een default implementatie mee kunnen leveren in een .lib.

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.


  • Boy
  • Registratie: November 2001
  • Laatst online: 10:05

Boy

www.byoscoop.nl

Topicstarter
.oisyn schreef op maandag 08 augustus 2005 @ 12:12:
[...]


Zo te horen wil jij gewoon een OO interface die je aan je DLL functies mee kunt geven, en die DLL roept gewoon weer (virtual) methods op dat object aan. Op die manier kan iedereen z'n eigen logger implementeren, en zou je evt. een default implementatie mee kunnen leveren in een .lib.
Klopt ongeveer, het is alleen geen OO, dus als ik een default implementatie meegeef, kan die niet overridden worden.

Op dit moment is het logging gedeelte aan te spreken via een class, de enige class eigenlijk waarvan de gebruiker gebruik maakt. Ik vind dit niet zo mooi.

Bij die andere .lib files wordt hij trouwens ook niet meegebouwd? hoe zit dat dan nou eigenlijk? Hij wordt wel in het project erbij gezet, alles in een library gezet, maar die .lib file heeft wel die c-file nodig. Dat is eigenlijk wat ik wil nu ik het zo bedenk.

Hij mag dan wel in het project zitten en de .lib/dll mag zien dat er een logfile is, maar niet meebouwen in de library/dll.

[ Voor 35% gewijzigd door Boy op 08-08-2005 12:21 ]

Naar de bioscoop? => gebruik de app op Byoscoop.nl


Verwijderd

.oisyn schreef op maandag 08 augustus 2005 @ 11:58:
Het nadeel hiervan is dat je je executable zelf niet kunt linken tegen de .lib van je dll (die heb je immers nog niet gebouwd)
Nu kan ik er naast zitten, maar ik geloof dat VC6 een dergelijke mutual dependency wel kon oplossen. Hoewel ik het zelf niet heb toegepast, meen in me te herinneren dat er een stuk over in de MSDN library stond hoe je dit moet oplossen.

Wat ik zelf handig vond bij het werken met C++ & DLL's: De DLL geen types laten exporten, maar andersom redeneren: De .exe exporteert interfaces die de DLL implementeerd. De DLL(s) kun je dan dynamisch laden met AfxLoadLibrary en je haalt er via GetProcAddress een pointer naar een well-known function uit die jou dan weer objecten terug geeft die de genoemde interface implementeerd.

Mischien is het wel triviaal wat ik nu zeg, maar iniedergeval heeft je .exe geen compile time dependencies op een specificieke DLL en kun je implementaties makkelijk uitwisselen.

Een klein addertje onder het gras is dat als je MFC gebruikt (ik zag dat je CString gebruikte), de MFC versies waarmee je de DLL en de .exe linkt overeen moeten komen.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:47

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op maandag 08 augustus 2005 @ 13:16:
Nu kan ik er naast zitten, maar ik geloof dat VC6 een dergelijke mutual dependency wel kon oplossen. Hoewel ik het zelf niet heb toegepast, meen in me te herinneren dat er een stuk over in de MSDN library stond hoe je dit moet oplossen.
Ah, idd
Exporting or importing to another executable file presents complications when the imports are mutual (or "circular"). For example, two DLLs import symbols from each other, similar to mutually recursive functions.

The problem with mutually importing executable files (usually DLLs) is that neither can be built without building the other first. Each build process requires, as input, an import library produced by the other build process.

The solution is to use the LIB utility with the /DEF option, which produces an import library without building the executable file. Using this utility, you can build all of the import libraries you need, no matter how many DLLs are involved or how complicated the dependencies are.
Zie MSDN, kopje "Mutual imports in DLLs"

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.


  • Boy
  • Registratie: November 2001
  • Laatst online: 10:05

Boy

www.byoscoop.nl

Topicstarter
Op deze manier wordt volgens mij wel wat meer implementatie verwacht aan de .exe kant. Dat kan helaas niet. M'n dll wordt ook extern gebruikt en ik kan niet gaan verwachten dat hun moeite moeten gaan doen om het een en ander aan het werken te krijgen.

Ik denk dat ik het even zo laat, de implementatie. Kost te veel tijd. Prioriteiten he :)

In ieder geval bedankt en ik ga hier later nog naar kijken! Waardeer de tips erg!

Naar de bioscoop? => gebruik de app op Byoscoop.nl


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
De klassieke C oplossing is om de functie @runtime mee te geven als callback. Triviaal, en elke ervaren programmeur ziet in 1 keer wat de bedoeling is van SetLogger( void *logGegevens(CString) );

PS. Als je een C file hebt, dan is CString niet handig. Of bedoel je een C++ file? Zelfs dan nog is de dependency op MFC/ATL onhandig.

[ Voor 10% gewijzigd door MSalters op 08-08-2005 14:09 ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Boy
  • Registratie: November 2001
  • Laatst online: 10:05

Boy

www.byoscoop.nl

Topicstarter
MSalters schreef op maandag 08 augustus 2005 @ 14:08:
De klassieke C oplossing is om de functie @runtime mee te geven als callback. Triviaal, en elke ervaren programmeur ziet in 1 keer wat de bedoeling is van SetLogger( void *logGegevens(CString) );

PS. Als je een C file hebt, dan is CString niet handig. Of bedoel je een C++ file? Zelfs dan nog is de dependency op MFC/ATL onhandig.
Ja, dat zou wel een mooie oplossing zijn. Ik zal het later zeker gaan proberen te implementeren.

Trouwens,

die logGegevens( CString ) is geen echte, was gewoon een voorbeeld. Het werkt via een char*. De log functies zijn puur C, degene die er gebruik van maken zijn C++

Naar de bioscoop? => gebruik de app op Byoscoop.nl

Pagina: 1