Live-Forum - Die aktuellen Beiträge
Datum
Titel
29.03.2024 13:14:12
28.03.2024 21:12:36
28.03.2024 18:31:49
Anzeige
Archiv - Navigation
956to960
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
956to960
956to960
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

DLL einbinden / Call Funktion

DLL einbinden / Call Funktion
28.02.2008 12:50:00
Helmut
Liebe Excel-Profis,
mich würde interessieren, wie man unter Excel 2003 eine externe DLL einbinden kann. Die DLL ist in C erstellt worden und bereits kompiliert. Mit folgendem Makro bekomme ich eine Fehlermeldung:
Declare

Function iris Lib "C:\Windows\system32\xyz.dll" (ByVal whichclass As Long, ByVal in1 As Double,  _
ByVal in2 As Double, ByVal in3 As Double, ByVal in4 As Double) As Double


Sub DLL()
Dim test As Double
Dim arg1 As Long
Dim arg2 As Double
Dim arg3 As Double
Dim arg4 As Double
test = iris(1, arg1, arg2, arg3, arg4)
End Sub


Beim Kompilieren stürzt Excel ab ("Excel muss beendet werden").
Bei Aufruf von =CALL("xyz.dll","iris",BIBBBB",1,a1,b1,c1,d1) kommt der Fehler "#NAME". Woran kö _ nnte es liegen? Laut Microsoft ist die "Call function" ja seit Excel 2000 standardmäßig deaktiviert ist. Es gab bereits für Excel 97 einen Patch der die Call funktion deaktiviert. Darin heißt es: "The patch disables the CALL


Function on worksheets only, not in macros."
Ich verstehe das so, dass die Funktion nicht mehr direkt aus einer Zelle aufgerufen werden kann  _
(bei Excel 97 benötigte man wahrscheinlich gar kein Makro zum Aufruf der Funktion).
Hat irgendjemand Vorschläge bzw. Erfahrung mit der Call Funktion und der Einbindung externer  _
DLLs?

13
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: DLL einbinden / Call Funktion
28.02.2008 18:40:00
Helmut
hat irgendjemand Erfahrung mit der Einbindung einer DLL bzw. Einbindung von C-Code unter Bezugnahme mathematischer Libraries in MS Excel2003?

AW: DLL einbinden / Call Funktion
28.02.2008 20:27:31
Volti
Hallo Helmut,
ich binde öfter mal selbstgemachte DLL's in Excelmakros ein und tue dies meistens so, wie Du es oben auch getan hast und wie alle Excelbeispiele die WINAPI-Funktionen verwenden es auch tun. Zwar sind meine DLL's mit PB und nicht mit C gemacht; dürfte aber egal sein.
Diese Form nennt sich early binding, es gibt noch eine andere Methode, nämlich late binding.
Das sollte eigentlich so funktionieren. Bist Du sicher, dass die DLL und die aufzurufende Funktion auch existieren? Hiermit kannst Du das ja mal prüfen:
Declare

Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As  _
Long
Declare 

Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Declare 

Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As  _
Long


Sub Dlltest()
hLib = LoadLibrary("C:\Windows\system32\xyz.dll")
If hLib = 0 Then Msg = "Keine passende DLL gefunden"
If hLib  0 Then
pProc = GetProcAddress(ByVal hLib, "iris")
If pProc  0 Then Msg = "Gewünschte Funktion wird unterstützt!"
FreeLibrary hLib
End If
MSGBOX Msg
End Sub


Wenn die gewünschte Funktion exportiert ist, also nicht nur in der DLL enthalten, sondern auch öffentlich zugänglich, sollest Du ein handle 0 über GetProcaddress erhalten.
DLL's sind empfindlich bei der Datentypübergabe. Ich erinner mich dunkel, dass es Argumentenübergabe von links nach rechts oder von rechts nach links gibt.
Probier doch einfach mal, die Reihenfolge der Argumentenübergabe zu drehen. Nur mal ein Tipp.
Dein Direktaufruf aus einer Zelle ist mir unbekannt; kann aber nicht funktionieren, da
1. BIBBBB" ohne führendes " beginnt und
2. ich nicht erkennen kann, dass dieses Argument, noch dazu ein String, überhaupt erwartet wird.
=CALL("xyz.dll","iris",BIBBBB",1,a1,b1,c1,d1)
viele Grüße und viel Erfolg
Karl-Heinz aus Freigericht

Anzeige
AW: DLL einbinden / Call Funktion
28.02.2008 21:25:15
Helmut
Hallo Karl-Heinz!
Erstmal recht herzlichen Dank für dein Makro. Ich hab's bei mir ausprobiert; ich bekomme die Meldung "Gewünschte Funktion wird unterstützt!". Soweit, so gut. Jetzt ist die Frage, wie ich das Ding zum Laufen bekomme. Unter Excel 97 gab es die Funktion CALL("xyz.dll","iris","BIBBBB",1,a1,b1,c1,d1) ...
das erste B von BIBBBB steht für den Rückgabewert (Double), das zweite für long integer für Input 0, aller weiteren B für Input 1-4.
In der DLL sind Koeffizienten eines nicht-parametrischen Regressionsmodells gespeichert. Es geht darum, dass man eine Formel erstellt, in der man zB. Spalte A-D als Inputfaktor angibt und die Funktion dann das Ergebnis der Regression liefert. Wie rufe ich die DLL auf bzw. wie mache ich eine Funktion daraus?

Anzeige
AW: DLL einbinden / Call Funktion
29.02.2008 20:15:00
Volti
Hallo Helmut,
leider kann ich Dir nicht weiter helfen, da die Aufrufmodalitäten über das Makro m.E. richtig sind, bzw. ich es aus der Ferne und unter Berücksichtigung der unbekannten DLL nicht besser weiß.
Deinen Aufruf aus einer Zelle unter Excel 97 kommt mir komisch vor. Ich habe hier zuhause selbst noch Excel 97. Da kriege ich keinen Aufruf in dieser Form hin und denke auch, dass das gar nicht gehen kann. Auch in der Hilfe ist zu dieser Aufrufform nichts beschrieben.
Was ich hinbekommen habe, ist tatsächlich aus einer Zelle eine meiner DLL-Funktionen aufzurufen. Analog zu deiner Vorgabe müsste es dann heißen:
=iris(1,a1,b1,c1,d1)
Die iris-Funktion ist über den DECLARE (nicht vergessen) inclusive der Parameter und deren Typen bekannt.
Hier mein funktionierendes Beispiel als Anregung:
Declare Function Hauptprogramm Lib "C:\PIV_ADD\PIV_Create.DLL" (Options As String) As Long
Und in einer Zelle:
=Hauptprogramm("Menü aufrufen")
viele Grüße
Karl-Heinz

Anzeige
AW: DLL einbinden / Call Funktion
01.03.2008 10:47:00
Helmut
Besten Dank!
Wenn ich iris direkt aufrufe, scheint Excel im Hintergrund zumindest den Versuch zu starten etwas berechnen zu wollen, nur bekomme ich dann sofort die Meldung: "Excel hat einen Fehler festgestellt und muss beendet werden". Mein Makro sieht folgendermaßen aus:
Private Declare

Function iris Lib "C:\Windows\system32\xyz.dll" (ByVal whichclass As Long, ByVal in1 As Double,  _
ByVal in2 As Double, ByVal in3 As Double, ByVal in4 As Double) As Double


Sub DLL()
End Sub


Die iris Funktion rufe ich auf mit: iris(1,a1,b1,c1,d1)
Woran könnte es liegen?

Anzeige
AW: DLL einbinden / Call Funktion
01.03.2008 13:48:13
Helmut
Voti, Danke für deine Hilfe!
Ich registriere die DLL via folgenden Makro:
Declare

Function iris Lib "C:\Windows\system32\xyz.dll" (ByVal whichclass As Long, ByVal in1 As Double,  _
ByVal in2 As Double, ByVal in3 As Double, ByVal in4 As Double) As Double


Sub DLL()
End Sub


Bei Aufruf von iris(1, arg1, arg2, arg3, arg4) stürzt allerdings Excel ab. Woran könnte es liegen. Unten habe ich dir den C-Code für die DLL angefügt. Das Komplieren der DLL funktioniert problemlos.
#include
#include
#include
#include
#include "recall.h"
__declspec(dllexport) double iris (long int whichclass, double in1,
double in2, double in3, double in4) {
float input[4];
float output[3];
double out;
input[0] = in1;
input[1] = in2;
input[2] = in3;
input[3] = in4;
NN_Recall ( (void*)0, input, output);
if (whichclass == 1) return ((double)output[0]);
else if (whichclass == 2) return ((double)output[1]);
else return ((double)output[2]);
out = (double)output[0];
return (out);
}
/* Thu Feb 28 09:16:03 2008 (recall.c) */
/* Header file is */
/* Recall-Only Run-time for */
/* Control Strategy is: */
#if defined(__STDC__) || defined(__cplusplus)
#define ARGS(x) x
#else
#define ARGS(x) ()
#endif /* __STDC__ */
#if defined(__cplusplus)
extern "C" {
#endif
/* --- External Routines --- */
extern double tanh ARGS((double));
/* *** MAKE SURE TO LINK IN YOUR COMPILER's MATH LIBRARIES *** */
#if defined(STATIC_WTS)
typedef struct _pewts {
short sPEFlag; /* Flag for weight type */
unsigned short usPESrc; /* index of source PE */
float fPEWt; /* value of weight for PE */
} PEWTS;
#define CN_VAR 0 /* variable weight */
#define CN_SET 2 /* set weight */
#define CN_MOD 3 /* mod weight */
#define ASof(x) (sizeof(x)/sizeof(x[0]))
#define SWC(x) x
#else
#define SWC(x)
#endif /* #if defined(STATIC_WTS) */
/* --- NOTE: Network has (Yin[4]) inputs and (Yout[3]) outputs --- */
#if defined(__STDC__) || defined(__cplusplus)
int NN_Recall( const void *NetPtr, const double *Yin, double *Yout )
#else
int NN_Recall( NetPtr, Yin, Yout )
void *NetPtr; /* Network Pointer (not used) */
double *Yin, *Yout; /* Data In=4 Out=3 */
#endif /* __STDC__ */
{
double Xout[13], Xsum[13]; /* work arrays */
long ICmpT=0; /* temp for comparisons */
/* *** WARNING: Code generated assuming Recall = 0 *** */
/* Read and scale input into network */
Xout[2] = (double)(Yin[0] * (2) + (-1));
Xout[3] = (double)(Yin[1] * (2) + (-1));
Xout[4] = (double)(Yin[2] * (2) + (-1));
Xout[5] = (double)(Yin[3] * (2) + (-1));
LAB107:
/* Generating code for PE 0 in layer (3) */
Xsum[6] = (-0.94772547) + (-0.98690498) * Xout[2] + (-0.47397092) * Xout[3] + 1.3767525 * Xout[4] +
0.77097577 * Xout[5];
/* Generating code for PE 1 in layer (3) */
Xsum[7] = 1.3693793 + 0.43019372 * Xout[2] + (-1.035066) * Xout[3] + 1.370787 * Xout[4] + 1.4604141 * Xout[5];
/* Generating code for PE 2 in layer (3) */
Xsum[8] = 0.59802961 + (-0.67472422) * Xout[2] + 0.0067717968 * Xout[3] + (-0.098248005) * Xout[4] +
(-1.4808481) * Xout[5];
/* Generating code for PE 3 in layer (3) */
Xsum[9] = 3.0767488 + 1.0973973 * Xout[2] + 0.27670342 * Xout[3] + (-5.163259) * Xout[4] + (-5.0406961) * Xout[5];
/* Generating code for PE 0 in layer (3) */
Xout[6] = (double)(tanh( Xsum[6] ));
/* Generating code for PE 1 in layer (3) */
Xout[7] = (double)(tanh( Xsum[7] ));
/* Generating code for PE 2 in layer (3) */
Xout[8] = (double)(tanh( Xsum[8] ));
/* Generating code for PE 3 in layer (3) */
Xout[9] = (double)(tanh( Xsum[9] ));
/* Generating code for PE 0 in layer (4) */
Xsum[10] = (-0.057100281) + (-0.21855229) * Xout[6] + (-1.1194284) * Xout[7] + 0.075954795 * Xout[8] +
(-0.15848683) * Xout[9];
Xout[10] = (double)(tanh( Xsum[10] ));
/* Generating code for PE 1 in layer (4) */
Xsum[11] = (-1.0244384) + 0.10323889 * Xout[6] + 1.1238164 * Xout[7] + (-0.68130648) * Xout[8] +
1.7236693 * Xout[9];
Xout[11] = (double)(tanh( Xsum[11] ));
/* Generating code for PE 2 in layer (4) */
Xsum[12] = (-0.043892719) + 0.053954735 * Xout[6] + 0.0030997731 * Xout[7] + 0.59573656 * Xout[8] +
(-1.5831093) * Xout[9];
Xout[12] = (double)(tanh( Xsum[12] ));
/* De-scale and write output from network */
Yout[0] = (double)(Xout[10] * (0.625) + (0.5));
Yout[1] = (double)(Xout[11] * (0.625) + (0.5));
Yout[2] = (double)(Xout[12] * (0.625) + (0.5));
/* Generating code for PE 2 in layer (4) */
return( 0 );
}
#if defined(__cplusplus)
}
#endif

Anzeige
AW: DLL einbinden / Call Funktion
01.03.2008 14:33:58
Volti
Hallo Helmut,
leider ist es für mich müßig, deinen C-Code zu analysieren, da ich C-ähnliche syntax nur von php, js und gwtel kenne und durch Lesen der Beispiele im Handbuchs für die WinApi. Ansonsten prgrammiere ich in Basis und zwar PowerBasic und VBA eben.
Aber jetzt zum Problem. Wenn ein Fehler in der DLL auftriit, (hatte ich auch schon) stürzt Excel unter Umständen ab und behauptet, es wäre ein Fehler in Excel gewesen. Dieser Fehler passierte aber in der DLL-Funktion unter der "Knute" von Excel.
Das kann also daran liegen, dass die Parameterübergabe nicht korrekt ist (sieht mir hier nicht so aus) oder dass bei der Berechnung innerhalb der DLL ein Fehler auftrat. Hierzu kann ich Dir nicht weiterhelfen, da ich C-Code nur beschränkt beherrsche.
PS: Die leere Sub DLL() nach dem Declare kannst Du vergessen. Die ist doch überflüssig.
Wenn Du willst, schicke mir die DLL per mail mit einem Beispiel, also was soll bei welchen Parametern rauskommen. Vieleicht kriege ich's von PB aus hin. "voltmann-khanCHR(64) t-onlineCHR(46)de"
Hast Du die DLL selbst gemacht? Dann wäre u.U. ein Debugging angesagt.
viele Grüße
KH

Anzeige
AW: DLL einbinden / Call Funktion
01.03.2008 15:12:00
Helmut
Hallo Karl-Heiunz,
die Dll findest du unter https://www.herber.de/bbs/user/50329.zip. Die DLL stammt von einem Softwareprodukt welches automatisiert C Flash Code erstellt, danach hab' ich sie mit vcvars32, cl-c usw. in der Command Prompt von Visual Studio Pro 05 kompiliert. Dabei ist kein Fehler aufgetreten. Ich gehe also mal davon aus, dass die DLL an sich intakt ist. Fraglich ist der Makro-Aufruf. Den kannst du ja mal bei dir probieren. Der Aufrug (nachdem =CALL nicht funktioniert) müsste dann mit =iris(1, Input1,Input2,Input3,Input4) erfolgen ... als Input kannst du irgendwelche Zahlen zwischen 0 und 1 heranziehen, die erste 1 im Aufruf =iris(1, ) steht für die Konstante im Regressionsmodell.
Viele Grüße und besten Dank!

Anzeige
AW: DLL einbinden / Call Funktion
01.03.2008 20:32:00
Volti
Hallo Helmut.
schlechte Nachrichten. Der Fehler ist nicht im Aufruf, sondern in Deiner DLL zu suchen.
Unter PB kann ich sie ansprechen, "but there is no return". Es kam zunächst zwar kein Fehler, aber auch keine Rückgabe. Später, nach mehreren Aufrufen mit anderen Werten stürzte sie auch ab.
Excel stürzt in allen Variationen einfach nur ab.
Es ist unerheblich, ob Du sie fehlerfrei kompilieren konntest. Das besagt ja nur, dass keine Syntaxfehler drin sind.
Also reparieren oder die Berechnung einfach in einer VBA-Funktion realisieren.
Tut mir leid, dass ich nicht helfen konnte.
viele Grüße
KH

Anzeige
AW: DLL einbinden / Call Funktion
01.03.2008 22:48:24
Helmut
vielen dank für deine bemühungen! da muss ich wohl den Fehler in der DLL selbst suchen...obwohl sie sich automatisiert erstellt, ist evtl. ein Fehler in den ersten Zeilen des C Codes drin. Evtl. finde ich ihn ja. Kannst du für den Fall der Fälle noch den entsprechenden Makroaufruf / Makrobefehlscode hier rein stellen, damit ich weiß wie ich sie aus Excel (via VBA)aufrufen könnte, wenn die DLL intakt wäre.
Besten Dank!

AW: DLL einbinden / Call Funktion
02.03.2008 13:29:22
Helmut
Hallo Karl.Heinz!
https://www.herber.de/bbs/user/50354.zip
Hab den Fehler in der DLL korrigiert (unter obigem Link findest du die neue DLL) ... sie stürzt jetzt nicht mehr ab ... jetzt bräuchte ich nur noch den Makrobefehl dazu wie ich die DLL per VBA aufrufe ... kannst du mir den hier rein stellen?
Mit:
Private Declare

Function iris Lib "C:\Programme\NeuralWare\NeuralWorks\Professional\xyz.dll" (ByVal whichclass  _
As Long, ByVal in1 As Double, ByVal in2 As Double, ByVal in3 As Double, ByVal in4 As Double) As Double


Sub DLL()
Dim test As Double
Dim arg1 As Long
Dim arg2 As Double
Dim arg3 As Double
Dim arg4 As Double
test = iris(1, a1, b1, c1, d1)
End Sub


funktionierts irgendwie noch nicht (Fehlermeldung: #Wert) bei Aufruf =iris(1,0.5,0.5,0.5,0.5)
Besten Dank!

Anzeige
AW: DLL einbinden / Call Funktion
02.03.2008 16:23:48
Volti
Hallo Helmut,
richtig Schwerstarbeit. :-))
Also, unter PB funktioniert das jetzt. Kriege super Ergebnisse.
Was war denn der Fehler? Division (durch 0 o.ä) war ja glaube ich nicht drin?
Aber unter VBA will es immer noch nicht. Jetzt kommt Fehler "49 falsche DLL-Aufruf Konvention".
Normalerweise würde ich das jetzt so aufrufen:
Declare

Function iris Lib "C:\Programme\NeuralWare\NeuralWorks\Professional\xyz.dll" (ByVal whichclass  _
As Long, ByVal in1 As Double, ByVal in2 As Double, ByVal in3 As Double, ByVal in4 As Double) As Double


Sub DLL()
Dim test As Double
Dim A1 As Double
Dim B1 As Double
Dim C1 As Double
Dim D1 As Double
A1 = Range("A1").Value
B1 = Range("B1").Value
C1 = Range("C1").Value
D1 = Range("D1").Value
test = iris(1, A1, B1, C1, D1)
MsgBox Str(test)
End Sub


Ich probier mal noch weiter. Habe aber im Moment keine Idee.
viele Grüße
KH

AW: DLL einbinden / Call Funktion
02.03.2008 18:23:00
Helmut
Hallo Karl-Heinz!
Auch ich bekomme unter VBA noch den Laufzeitfehler 49. Habe dazu (zur Einbindung einer DDL in VBA ) aber einen guten Link gefunden ... vielleicht hilft der ja:
http://www.microsoft.com/germany/msdn/library/office/OfficeVBAUndDieWindowsAPI.mspx?mfr=true
Außerdem schick ich dir nochmal den kompilierten C Code mit. Wenn du die DLL in PowerBasic aufrufen kannst, müssten wir das in VBA auch irgendwie noch hinbekommen ;.))
In deiner Mailbox findest du recall.c und recall.h.

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige