VS C++ DLL in VB einfügen



  • Hallo,

    ich habe mich bereits durch zwei Bücher durchgeschlagen und Google gequält, doch leider bin ich weder mit dem einem noch dem anderen zurechtgekommen. Ich bin aber auch noch ein ziemlicher Anfänger in solchen Sachen.

    Ich habe eine C++ Anwendung geschrieben und diese dann in eine DLL konvertiert.
    Die DLL möchte ich in einen bereits bestehenden VB-Code einfügen und später zwei zweidimensionale Felder übergeben und einen double Wert zurück bekommen.

    Zum Testen übergebe ich bis jetzt allerdings noch keine Felder, lasse mir aber dennoch einen Wert zurückgeben der in der DLL berechnet wird. Dies geht, weil ich die Felder bis jetzt einfach in der DLL vorgegeben haben. Wenn ich die C++ Anwendung so über die Konsole ausführe funktioniert alles bestens. Wenn ich jedoch die DLL in VB aufrufe wird VB augenblicklich beendet. Ich habe keine Ahnung was die Ursache dafür ist. Ich habe hier mal meinen C++ Header und die Main-Funktion angegeben. Unten steht die Deklaration der Funktion in VB und deren Aufruf.

    Ich habe schon viele Varianten durchprobiert aber es passiert immer das gleiche.

    /*Header-Datei*/
    #ifndef MR_H
    #define MR_H
    
    #include<iostream>
    #include<string>
    #include<cmath>
    
    using namespace std;
    
    extern "C" __declspec(dllexport) void main(double*);
    
    #endif
    
    -------------------------------------------------------------------------
    /*Main-Datei*/
    #include "MR.h"
    
    void main(double* DQ)
    {
    	/*Variablen Deklaration*/
    	const double PI = 3.14159265;
    	int iDim = 28;
    	int iDim_R;
    	double abstand = 141.421;
    	double abstand_R;
    	double id  = 2000;
    	double r = id / 2;
    	double r_BP = 81.923;
    	short i;
    	int geoTyp = 1;
    	int Verteilung = 1;
    	double L_Wert;
    	double G_Wert;
    	double T_Wert;
    
    int* lageBP_Data;
    	double* xKoordinaten_Data;
    	double* yKoordinaten_Data;
    	float* XR_Data;
    	float* YR_Data;
    	char* AnzahlUeberschneidungen_Data;
    	double* xhLinienKoordinaten_Data;
    	double* yvLinienKoordinaten_Data;
    
    	int** lageBP;
    	double** xKoordinaten;
    	double** yKoordinaten;
    	float** xKoordinaten_R;
    	float** yKoordinaten_R;
    	char** AnzahlUeberschneidungen;
    	double** xhLinienKoordinaten;
    	double** yvLinienKoordinaten;
    
    	abstand_R = dimR(id);
    	iDim_R = dimFeld(id, abstand_R);
    
    	/*Speicherreservierung für ein dynamisches einiDimensionales Feld*/
    	lageBP_Data = new int[iDim *iDim];
    	xKoordinaten_Data = new double[iDim * iDim];
    	yKoordinaten_Data = new double[iDim * iDim];
    	XR_Data = new float[iDim_R * iDim_R];
    	AnzahlUeberschneidungen_Data = new char[iDim_R * iDim_R];
    	YR_Data = new float[iDim_R * iDim_R];
    
    	/*Speicherreservierung für ein dynamisches Feld von Zeigern, welche auf die Zeilenanfänge weisen*/
    	lageBP = new int*[iDim];
    	xKoordinaten = new double*[iDim];
    	yKoordinaten = new double*[iDim];
    	xKoordinaten_R = new float*[iDim_R];
    	yKoordinaten_R = new float*[iDim_R];
    	AnzahlUeberschneidungen = new char*[iDim_R];
    
    	/*Zuweisung der Zeilenanfänge*/
    	for(i = 0; i < iDim_R; i++)
    	{
    		xKoordinaten_R[i] = XR_Data + i * iDim_R;
    		yKoordinaten_R[i] = YR_Data + i * iDim_R;
    		AnzahlUeberschneidungen[i] = AnzahlUeberschneidungen_Data + i *iDim_R;
    	}
    
    	for(i = 0; i < iDim; i++)
    	{
    		xKoordinaten[i] = xKoordinaten_Data + i * iDim;
    		yKoordinaten[i] = yKoordinaten_Data + i * iDim;
    		lageBP[i] = lageBP_Data + i * iDim;
    	}
    }
    

    VB-Code:

    Module:

    Declare Function main Lib "Pfad" (ByRef pDQ) As Double

    Main:

    Dim pDQ
    main (pDQ)

    Ich vermute, dass mein Syntax für die DLL falsch ist. Kann mir jemand sagen wo meine Fehler sind?

    Vielen Dank im Voraus!
    Grüße



  • Dieser Beitrag hilft dir nicht weiter, achtung!

    Mach doch bitte die code-tags um den code.

    #include <iostream>
    
    int main()
    {
        std::cout << "Hallo world from a very well formatted Forum beitrag!\n";
        return 0;
    }
    

    Bitte beschränk dich aufs mindeste. Du kannst das mindeste hier reinschreiben und sonst noch auf www.Pastebin.com verweisen mit 100% des codes.



  • lk schrieb:

    Dieser Beitrag hilft dir nicht weiter, achtung!

    Mach doch bitte die code-tags um den code.

    int main()
    {
        printf("Hallo world from a very well formatted Forum beitrag!\n");
        return 0;
    }
    

    Bitte beschränk dich aufs mindeste. Du kannst das mindeste hier reinschreiben und sonst noch auf www.Pastebin.com verweisen mit 100% des codes.

    Wenn du ihn schon ausbesserst, dann bitte nicht mit printf. Danke.

    Edit:
    Ausnahme, wenn printf ähnlich wie folgt definiert wurde:

    void printf(const char* str)
            {
                    std::cout << str;
            }
    
            template <typename Head, typename... Tail>
            void printf(const char* str, Head&& head, Tail&&... tail)
            {
                    while(*str != '%')
                            std::cout << *str++;
    
                    std::cout << head;
                    printf(++str, std::forward<Tail>(tail)...);
            }
    


  • Das ist meiner Meinung nach schon das Minimalbeispiel.
    Kann mir denn keiner helfen?
    Gruß


  • Mod

    asdfghjkl1234 schrieb:

    Das ist meiner Meinung nach schon das Minimalbeispiel.
    Kann mir denn keiner helfen?
    Gruß

    Lies dir die Antwort von ik durch. Als Registrierter kannst du deinen Beitrag im Nachhinein ändern. So wie deine Eingangsfrage derzeit aussieht schließt man als Leser den Thread sofort wieder ohne ihn zu lesen. Und auch Codetags würden nicht helfen. Das ist kein Minimalbeispiel! Wen interessieren die 100 Funktionen die du das hast? Kannst du dein Problem nicht an einer Testanwendung mit einer einzigen Funktion verdeutlichen?



  • Also Strings musste ich in VBA immer byValue einbinden, sonst muss man in C/C++ noch dereferenzieren. Haste das für deine 2dim-Arrays bedacht?



  • Eine .dll unter windows kennt kein "main" als Einsprungspunkt, sondern nur DllMain:
    http://msdn.microsoft.com/en-us/library/ms682583(v=vs.85).aspx
    Wobei void main() mir alle Nackenhaare sträuben lässt. Benenn die Funktion sinnvoll.

    Ansonsten:
    http://www.shadoware.de/vb/tutorials/cpp_in_vb.html

    Und benutze bitte [ cpp ] tags.



  • Ich habe es jetzt einmal mit dieser Variante probiert nur leider stürzt VB jetzt immer nach dem Funktionsaufruf ab.

    Deklaration

    Declare Function MooreRukovenaDLL Lib "C:\...\MooreRukovenaDLL.dll" Alias "_MooreRukovenaDLL@4" (ByRef p As Double) As Double
    

    Aufruf

    MooreRukovenaDLL (DQ)
    

    C++

    extern "C"  __declspec(dllexport)  void WINAPI MooreRukovenaDLL(double*);
    
    void WINAPI MooreRukovenaDLL(double* Dq)
    {
    *DQ = 1;
    }
    

    Habe nur alle möglichen Varianten durch probiert und keine führt zum Ziel.
    Ich bin mit meinem Latein am Ende...



  • du hast die Funktion in VB mit dem return-type double deklariert. In deinem c++ code ist der aber void. Moeglich das es daran liegt.

    gruss
    Dirk





  • Ich habe den Fehler jetzt eingegrenzt.

    Und zwar deklariere ich in der DLL zwei 2D dynamische Float Felder, mit ca. 11000 Elementen in jeder Dimension. Wenn ich eines der Felder, egal welches, auskommentiere funktioniert meine DLL. Nur wenn ich beide zur gleichen Zeit verwende stürzt Excel ab.

    Ich verstehe den Fehler nicht. Könnte es darin liegen, das die beiden Felder zusammengenommen für eine DLL zu groß sind?
    Als Exe funktioniert der Code wunderbar.



  • Excel - DLL - VB oder VBA?
    Je nach Version sind die Limits anders.
    Hier mal ein Beispiel aus 2006:
    http://www.xlam.ch/xlimits/visualbasic.htm

    Keine Ahnung ob du damit in Konflikt kommst?
    Hier noch so was:
    http://www.xlam.ch/xlimits/arrays.htm

    MfG f.-th.


Log in to reply