Probleme bei Übergabe des Wertes an Vba

Hallo,

also meine Funktion ist relativ leicht aufgebaut: es soll eine dezimalzahl in hex umwandeln und dann wieder an Excel zurück geben, jedoch stürzt das program einfach ab:

char *int2hex(int dezimalzahl)
{
sprintf(zielPuffer, „%X“, dezimalzahl);
return zielPuffer;
}

Der Vba code lautet wie folgt

_Declare Function dezi2hexa Lib „test.dll“ Alias „_int2hex@4“ _
(ByVal ver As Integer) _
As String

Sub test()
Dim a As Integer
a = 11
MsgBox dezi2hexa(a)

End Sub_

jedoch stürzt excel einfach so ab…woran könnte das liegen?

Danke im voraus

Johannes

Hallo,

also meine Funktion ist relativ leicht aufgebaut: es soll eine
dezimalzahl in hex umwandeln und dann wieder an Excel zurück
geben, jedoch stürzt das program einfach ab:

char *int2hex(int dezimalzahl)
{
sprintf(zielPuffer, „%X“, dezimalzahl);
return zielPuffer;
}

jedoch stürzt excel einfach so ab…woran könnte das liegen?

Kann man nicht sagen, wenn man den Rest des
Programms nicht kennt. meine Glaskugel sagt
mir aber, daß ‚zielPuffer‘ als

 char \* zielPuffer;

deklariert wurde. Falls kein Speicher zugewiesen
wurde, kommt es in der Funktion zum „Speicherfehler“.

Grüße

CMБ

Hallo CMБ,

also, folgendes ist noch hinzugefügt:

#include 

char \*zielPuffer;
int dezimalzahl;

extern "C" \_\_declspec(dllexport) char \*int2hex(int dezimalzahl);

vielen dank

Johannes

Hallo CMБ,

also, folgendes ist noch hinzugefügt:

#include

char *zielPuffer;
int dezimalzahl;

extern „C“ __declspec(dllexport) char *int2hex(int
dezimalzahl);

Ja genau. Dann hast Du jetzt verstanden,
woran es lag?

Viele Grüße

CMБ

Hallo CMБ,

nein, leider nicht, es stürzt trotzdem einfach ab

Vielen Dank

Johannes

Hallo,

mach mal teshalber aus:

 char \*zielPuffer;

die Zeile

 char zielPuffer[4096];

(’*’ nicht vergessen zu löschen)

und versuche, das programm/die dll neu zu
übersetzen und zu testen. Was passiert?

Grüße

CMБ

Was passiert?

Hallo CMБ

es stürzt zumindestens erstmal nicht mehr ab… aber der gibt nun einfach einen leeren wert zurück

vielen Dank dass du so geduldig mit mir bist!

Johannes

Hallo allerseits,

das Problem ist, dass das Ganze so nicht funktioniert, denn VBA kennt keine „char*“.

In den Schnittstellen zwischen VBA und C++ wird in der Regel der Typ BSTR benoetigt, also sowas wie

BSTR X\_EXPORT dezi2hexa (int dezimalzahl)

wobei BSTR entweder ein Pointer auf plain null-terminated ASCII Strings ist oder ein Pointer auf null-terminated Unicode Chars, siehe auch http://msdn.microsoft.com/en-us/library/ms221105.aspx

Das __declspec wird in der Regel bei DLLs durch ein X_EXPORT Makro ersetzt, welches entweder zu Import (Headerfilebenutzer) oder Export (Implementierung) expandiert.

Zurueckgegeben wird nichts statisches, sondern ein Wert, der von einer der SysAlloc Funktionen allokiert wurde.

Fuer den non-unicode Fall koennte die Funktion also wie folgt aussehen;

BSTR X\_EXPORT dezi2hexa (int dezimalzahl)
{
 char szTemp[128];
 (void) snprintf(szTemp,sizeof(szTemp),"%X", dezimalzahl);
 return ::SysAllocString(szTemp);
}

Sehr wahrscheinlich musst du die Funktion aber als Unicode Variante schreiben.

Gruss
norsemanna

Hallo Johannes,

ich selbst habe noch nie vb programmiert, kann dir also nichts über die Speicherverwaltung sagen. Prinzipiell musst du aber bei deiner Funktion aufpassen:

Folgender Code liefert bei mir 2 2 als Ausgabe:

#include

char *buffer;

char *int2hex(int x){
sprintf(buffer,"%X",x);
return buffer;
}

int main(){
buffer=new char[1024];
char *erg1=int2hex(1);
char *erg2=int2hex(2);
printf("%s %s",erg1,erg2);
return 0;
}

Das liegt daran, int2hex die (virtuelle) Speicheradresse von buffer zurück gibt. Der Zugriff auf erg1 und erg2 ist folglich das Selbe.

besser wäre folgendes:

#include

void int2hex(int x, char *buffer){d
sprintf(buffer,"%X",x);
}

int main(){
char *erg1=new char[2], *erg2=new char[2];
int2hex(1,erg1);
int2hex(2,erg2);
printf("%s %s",erg1, erg2);
return 0;
}

Dieser Code erzeugt die erwünschte Ausgabe 1 2.
Was jetzt noch fehlt ist eine Längenüberprüfung bzw. das Bereitstellen von übermäßig viel Speicher (char *erg1=new char[4096], *erg2=new char[4096]:wink:

@CMБ: Wo gibt es solche Glaskugeln?