# DLL aus VC++ anbinden



## scherbel_mousa (10. September 2004)

Liebe Programmierer, 

ich habe eine DLL zum ausprobieren bekommen.
Die DLL  hat drei Aufgaben:
1. MsgBox aufrufen
2. ein String in einer MsgBox darzustellen
3. liefert ein Wert zurück (1.23456)

im Anhang findet ihr die DLL ihrer VC++ Quellcode.

Wie binde ich diese DLL in VB 6.0? kann jemand mir ein Beispiel bezogen auf die DLL im Anhang basteln.

Mit freundlichen Grüßen
Scherbel


----------



## scherbel_mousa (10. September 2004)

Der Anhang ist zu Groß,
hier ist der Quellcode (VC++):

CCtcConfig::CCtcConfig()
{
}
CCtcConfig::~CCtcConfig()
{
}
CCtcConfig::Test1(void)
{
	MessageBox ( 0 , "DLL-Aufruf erfolgreich" , "Moin" , MB_OK ) ; 
}

CCtcConfig::Test2(std::string sMyString)
{
	MessageBox ( 0 , sMyString.data(), "Moin" , MB_OK ) ; 
}

double CCtcConfig::Test3(void)
{
	return(1.2345);
}


----------



## MAN (13. September 2004)

Habe den Code jetzt nicht ausprobiert, aber so sollte es funktionieren:

```
Private Declare Function Test1 Lib "ctctest.dll" ()
Private Declare Function Test2 Lib "ctctest.dll" (ByVal sMyString As String)
Private Declare Function Test3 Lib "ctctest.dll" () As Double

Private Sub Form_Load()
   Call Test1

   Call Test2("Das ist ein Test")

   Dim doubleWert As Double
   doubleWert = Test3()
   Msgbox "doubleWert: " & doubleWert
End Sub
```
Eventuell must du die DLL noch ein wenig anpassen. Ich weiß nicht, wie das mit Klassen in einer DLL ist (zu sehen am Konstruktor und Destruktor).

Einfach mal ausprobieren!


mfG,
MAN


----------



## scherbel_mousa (13. September 2004)

Vielen Dank für die schnelle Antwort. Wirklich nett   
Ich habe folgendes Probiert:

Private Declare Function Test1 Lib "ctctest.dll" ()

Private Sub Form_Load()
   Call Test1

End Sub

Dann kam die Fehlermeldung:
DLL-Einsprungpunkt Test1 in ctcdll.dll nicht gefunden.

Die DLL-Datei befindet sich im gleichen Verzeichnis wie das VB-Project


----------



## MAN (13. September 2004)

Dann ist es so, wie ich es schon vermutet habe: Du must die DLL ein wenig umschreiben und zwar in der Art (wie auch in dem anderen Beitrag):

```
__declspec(dllexport) void __stdcall Test1( void )
{
   MessageBox ( 0 , "DLL-Aufruf erfolgreich" , "Moin" , MB_OK ) ;
}
```

mfG,
MAN


----------



## scherbel_mousa (15. September 2004)

Ich habe es fast geschafft, Bezogen auf die Beispiele unter dem Link:
http://www.mvps.org/EDais/Tutorials/CDLL/CDLLch1a.html
und die Hilfe vom MAN (Super nett und sehr hilfsbereit )habe ich das Beispiel wie folgt verändert:

// VCDLL.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <string>

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

int _stdcall ReportVersion() {
	return 1;
}

//***************************

void _stdcall Test1( void )
{
	MessageBox( 0 , "DLL-Aufruf erfolgreich", "Moin", MB_OK ) ;
}
void _stdcall Test2( std::string sMyString )
{
	MessageBox( 0 , sMyString.data(), "Moin" , MB_OK ) ; 
}
double _stdcall Test3( void )
{
	return 1.2345;
}

und in der Datei VCDLL.def habe ich Test1 bis Test3 eingetragen.


In VisualBasic:
Hier habe ich die Vorschläge vom MAN befolgt. Test1 und Test3 Liefen Ohne Probleme. Bei Test2 hat es gehackt. Das Programm stürzte ab (Debug Assertion Failed).
Lieber MAN Du bist echt Klasse. Bitte Um Hilfe.
Danke im Voraus


----------



## MAN (15. September 2004)

Also hier steht zum Beispiel genau drin, wie du eine DLL in Visual C++ Schritt für Schritt programmierst: http://www.mvps.org/EDais/Tutorials/CDLL/

Ich dachte, dass du schon alles davon programmiert hast, dir nur noch die Schnittstelle fehlt!

Hab mir dein Projekt angekuckt und verbessert. Mustes nur noch kompilieren.

Was ich jetzt vergessen hab: du must noch die .def-Datei aus dem Archiv in dein Proekt einbinden. Einfach bei QuellcodeDateien rechte Maustaste => Datei hinzufügen => CtcConfig.def angeben => Öffnen => neu kompilieren => fertig!


mfG,
MAN


----------



## MAN (15. September 2004)

Benutze einfach statt *std:string* _char*_:

```
__declspec(dllexport) void __stdcall Test2( char* sMyString )
```
Dann müßte es theoretisch gehen (habs nicht ausprobiert)


mfG,
MAN


----------



## scherbel_mousa (16. September 2004)

Wie Du vorgeschlagen hast, Habe ich die Funk. Test2 wie folgt geändert

//void _stdcall Test2( std::string sMyString ) 
_declspec(dllexport) void __stdcall Test2( char* sMyString )

{
	MessageBox( 0 , sMyString.data(), "Moin" , MB_OK ) ; 
}

Somit Kam die die Fehler Meldung:
Der linke Teil von '.data' muss eine Klasse/Struktur/Union sein 

dann habe ich .data() die in dem Aufruf von der MessageBox gelöscht und wie folgt geändert. 
MessageBox( 0 , sMyString, "Moin" , MB_OK ) ; 
Die DLL wurde dann erstellt. 
Als ich Test2 von VB aus aufgerufen habe, 

Private Declare Function Test2 Lib "vcdll.dll" (ByVal sMyString As String)
...
...
Call Test2("WWW")

kam eine leere MsgBox und zeigte den Folgenden Fehler an:
Falsche DLL-Aufrufkonvention

Was muss ich noch ändern Bitte um Hilfe


----------



## MAN (16. September 2004)

Dann versuch doch nochmal, das mit dem string in der DLL zu machen, aber ein wenig anders, und zwar so:


```
#include <string>

__declspec(dllexport) void __stdcall Test2( char* sMyString )
{
   std:string sMessage = sMyString;

   MessageBox( 0 , sMessage.data(), "Moin" , MB_OK );
}
```
Dabei kannst du den Aufruf von VB lassen.
Wenn das nicht funktioniert, wüßt ich auch nicht weiter, da ich das genau so selbst gemacht hatte.


mfG,
MAN


----------



## scherbel_mousa (16. September 2004)

Vielen Dank Lieber MAN

Jetzt hat es FUNKTIONIERT, wirklich KLASSE Danke MAN
Den Aufruf in VB musste ich aber auch ändern:
Private Declare Function Test2 Lib "vcdll.dll" (ByVal sMyString As String) As Long

Noch mal möchte ich den MAN loben. 

Keiner könnte mir so Hilfen wie Er. 
1000000 Dank


----------



## MAN (16. September 2004)

Ist ja gut  - ich fühl mich geehrt!

Aber nochmal zu dem "As Long": das brauchst du nur, wenn du deine Funktion noch umschreibst und einen Long-Wert zurückgeben läßt. Wenn du die Funktion aus meinem letzten Post nimmst, gibt es ja keinen Rückgabewert.

Aber wenn jetzt alles so läuft wie du es haben wolltest, dann ist ja alles klar! 


mfG,
MAN


----------



## scherbel_mousa (16. September 2004)

Ich Brauch keine Rückgabewert aber anders hat es nicht funktioniert

Danke noch mal für die tolle Hilfe


----------



## JapanHauke (22. Oktober 2007)

Hallo MAN und scherbel_mousa,
ich stehe vor einem ähnlichen Problem (glaube ich) und würde mich freuen, wenn Ihr mir Eure Testapplikation zuschicken könntet.
Merci!
Hauke


----------

