# Anfängerfrage: Problem beim Einbinden von Library

• Hallo!

Ich habe mir die CVODE library von sundials auf Windows installiert, um damit später in einem C Programm DGLs zu lösen.

Um es auszuprobieren, habe ich ein Beispiel, das ich gegooglet habe, gebaut.

http://www.cs.nyu.edu/courses/spring09/G22.2112-001/hw/hw10ex/hw10ex.pdf

Mein Programm main.c sieht also so aus

``````#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <cvode/cvode.h>
#include <nvector/nvector_serial.h>
#include <cvode/cvode_dense.h>
#include <sundials/sundials_dense.h>
#include <sundials/sundials_types.h>

static int f(realtype t, N_Vector y, N_Vector ydot, void *f_data)
{
realtype theta = NV_Ith_S(y,0);
realtype omega = NV_Ith_S(y,1);
realtype omegap = -sin(theta);
NV_Ith_S(ydot,0) = omega;
NV_Ith_S(ydot,1) = omegap;
return 0;
}

int main(int argc, char** argv)
{
int N = 200;
realtype T0 = 0;
realtype Tfinal = 10;
realtype theta0 = atof(argv[1]);
realtype reltol = 1e-6;
realtype abstol = 1e-8;
realtype t;
int flag, k;
N_Vector y = NULL;
void* cvode_mem = NULL;
/* Create serial vector of length NEQ for I.C. */
y = N_VNew_Serial(2);
NV_Ith_S(y,0) = theta0;
NV_Ith_S(y,1) = 0;
/* Set up solver */
if (cvode_mem == 0) {
fprintf(stderr, "Error in CVodeMalloc: could not allocate\n");
return -1;
}
/* Call CVodeMalloc to initialize the integrator memory */
flag = CVodeMalloc(cvode_mem, f, T0, y);//, CV_SS, reltol, &abstol);
if (flag < 0) {
fprintf(stderr, "Error in CVodeMalloc: %d\n", flag);
return -1;
}
/* In loop, call CVode, print results, and test for error. */
for (k = 1; k < N; ++k) {
realtype tout = k*Tfinal/N;
if (CVode(cvode_mem, tout, y, &t, CV_NORMAL) < 0) {
fprintf(stderr, "Error in CVode: %d\n", flag);
return -1;
}
printf("%g %.16e %.16e\n", t, NV_Ith_S(y,0), NV_Ith_S(y,1));
}
N_VDestroy_Serial(y); /* Free y vector */
CVodeFree(&cvode_mem); /* Free integrator memory */
return(0);
}
``````

Die order lib und include im verzeichnis C:\Program Files\Sundials habe ich in die systemumgebungsvariablen hinzugefügt.

Wenn ich jetzt kompiliere mit cl main.c, dann kommt der Fehler:

``````cl main.c
Microsoft (R) C/C++-Optimierungscompiler Version 19.00.23506 für x64
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.

main.c
Microsoft (R) Incremental Linker Version 14.00.23506.0

/out:main.exe
main.obj
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_CVodeCreate" in Funktion "main".
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_CVode" in Funktion "main".
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_CVodeFree" in Funktion "main".
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_N_VNew_Serial" in Funktion "main".
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_N_VDestroy_Serial" in Funktion "main".
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "CVodeMalloc" in Funktion "main".
main.exe : fatal error LNK1120: 6 nicht aufgelöste Externe
``````

Muss ich in die Kommandozeile irgendwelche Optionen einfügen? der Compiler kann die #include alles auch laden, denn wenn ich sie weglasse, erkennt er andere Variablen nicht. Warum also kann er diese Funktionen nicht verlinken??

Ich freue mich, wenn ihr mir helfen könnt!

Viele Grüße

Kryo

• Du musst die Bibliothek(en) statisch Linken, das geht in vielen IDE's unter Project-Options und dann Linker-Settings.

• im not using any ide... cant i do this with a command line option? seems much less difficult than to get myself used to visual studio...

• Ist ja ein deutsches Forum oh gott xD

Also: ich nutze keinen IDE... und es wird viel mehr aufwand sein mich z.b in visual studio einzuarbeiten.. kann ich das auch mit nem command line befehl? ich bekomme es leider nicht hin...

• Ja kannst du, müsstest du dir aber selbst ergooglen wie das mit dem C-Compiler von Microsoft funktioniert.

• Du musst deine Lib auch noch explizit angeben, nur den Libpfad einstellen, ist zu wenig.
Also

``````cl bla.c mylib.lib
``````

• Wutz schrieb:

Du musst deine Lib auch noch explizit angeben, nur den Libpfad einstellen, ist zu wenig.
Also

``````cl bla.c mylib.lib
``````

danke, aber das hatte ich schon probiert.

``````cl main.c sundials_cvode.lib sundials_nvecserial.lib
Microsoft (R) C/C++-Optimierungscompiler Version 19.00.23506 für x86
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.

main.c
Microsoft (R) Incremental Linker Version 14.00.23506.0

/out:main.exe
main.obj
sundials_cvode.lib
sundials_nvecserial.lib
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__CVodeCreate" in Funktion "_main".
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__CVode" in Funktion "_main".
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__CVodeFree" in Funktion "_main".
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__N_VNew_Serial" in Funktion "_main".
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__N_VDestroy_Serial" in Funktion "_main".
main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_CVodeMalloc" in Funktion "_main".
main.exe : fatal error LNK1120: 6 nicht aufgelöste Externe
``````

langsam hege ich den Verdacht, dass die besagten Funktionen gar nicht in den libraries drin sind. (die habe ich ja heruntergeladen von sundials.

• Es gibt auch

``````lib.exe /LIST mylib.lib
``````

• Hallo nochmal danke für die Hilfe bisher. Freitag abend habe ich durch Forumsuche herausgefunden, dass es mit Microsoft-Compilern und der Sundials software Probleme gibt. Also habe ich MinGW und msys installiert um es mit gcc zu kompilieren.

Das funktioniert auch. Mit dem Befehl

``````gcc main.c -o main.exe -lsundials_nvecserial -sundials_cvode
``````

funktioniert das Kompilieren ohne Fehler.

Die Libs sind 3 dateien pro library und das kompilieren funktioniert nur, wenn alle 3 dateien mit den endungen .a, .dll und .dll.a im LIB ordner sind. Wenn eine der 3 fehlt, funktioniert es auch nicht. Dann findet er wieder die Reference zu den Befehlen in der Lib nicht, also der altbekannte Fehler.

Das Problem, das ich nun habe, ist, dass wenn ich main.exe starte, kommt eine Windowsfehlermeldung, dass die libsundials_nvecserial.dll und libsundials_cvode.dll auf dem Computer fehlt.

Fehlt bei meinem Befehl etwas? Online fand ich -static, doch das funktioniert auch nicht. Dann findet der Kompilierer die libs wieder nicht.

Wäre super, wenn ihr euch das nochmal anschauen könntet. ich kann auch die Dateien zur Verfügung stellen, wenn es hilft.

• hat sich gelöst. Hab den ganzen Prozess mit MINGW und msys neu gemacht und beim erstellen der libraries darauf geachtet nur static zu erstellen, dann gings auf einmal.