# Funktion aufrufen und Char-String zurückgeben



## MartinFS (29. März 2005)

Hallo,

habe mal wieder ein Problem.
Ich möchte aus meinem main-Programm (main.cpp) eine Funktion aus einer anderen Übersetzungseinheit (serial.cpp) aufrufen, dabei eine String übergeben und ein Ergebnis-String zurückbekommen.

Funktionsdeklaration in der serial.cpp:

char serial_main( int argc, char **argv )

Aufruf aus der main-Datei dachte ich mir ganz blöd:

char *rueckgabewert = serial_main(zeichen, *string)

Funktioniert selbstverständlich nicht.... nur wie isses richtig und was muss ich in diese ominöse Header Datei schreiben?
Habe leider kein wirklich gutes Beispiel gefunden, bei dem mir die korrekte Deklaration, etc... verständlich wird.

Wäre über Hilfe dankbar.


gruß,
MartinFS


----------



## uhu01 (29. März 2005)

Hy!

Wenn du der Funktion eine char-Array übergeben willst darfst du nicht

```
char **argv
```
sondern musst du 

```
char *argv
```
Das char** argv ist ein String-Array, also ein Array von Char-Arrays.

die Funktionsdefinition muss dementsprechend auch anders aussehen, nämlich:

```
char *serial_main( int argc, char *argv )
```
Du musst nur aufpassen, das du nicht ein Array zurückgibst (eigentlich nur ein Pointer) welches nach Aufruf wieder zerstört wird.
Entweder du legst es auf den Heap (mit malloc) oder du übergibst der Funktion ein leeres Array, welches du dann füllst.

mfg
uhu01


----------



## MartinFS (29. März 2005)

Hi,

Danke für die Antwort.

Hier mal etwas mehr Code.

main.cpp:

```
....
int zeichen = 7; 
char *string = "Diesen Text moechte ich gerne uebergeben";  
printf ("%s\n",string);  
printf ("%i\n", zeichen);  
char *rueckgabewert = serial_main(zeichen, *string);  
printf("%s\n", *rueckgabewert);
...
```


serial.cpp:

```
char *serial_main( int argc, char *argv )
```

jedoch kommt dann bei der main.cpp die Compiler-Meldung:

Compiling...
main.cpp
main.cpp: In function `int main()':
main.cpp:16: error: `serial_main' undeclared (first use this function)
main.cpp:16: error: (Each undeclared identifier is reported only once for each
function it appears in.)

main.o - 2 error(s), 0 warning(s))



Die beiden Fehlermeldungen verwirren mich leider "etwas".



Das mit dem Array war wirklich blöd.. es soll lediglich ein String zurückgegeben werden.

Welchen Vorteil hätte da denn ein heap?


----------



## uhu01 (29. März 2005)

Hy!

Diese Fehlermeldung kommt daher, das du deine Funktion nicht deklariert hast, also ein 

```
char *serial_main( int argc, char *argv )
oder
extern char *serial_main( int argc, char *argv )
```
zweiter Fehler: du übergibst deiner Funktion den ersten Buchstaben deines Strings, anstelle des Strings selbst. Du musst deiner Funktion string, und nicht *string übergeben.

Das mit dem Heap ist so:

wenn du in einer Funktion z.B. char str[20]; anlegst,(das kommt auf den Stack) und du dann am Ende der Funktion ankommst wird das char-Array wieder gelöscht, da der Stack der rufenden Funktion wiederhergestellt wird. Das heißt, wenn du nun str zurückgibst (also die Adresse des ersten Elements) gibt es den String garnicht mehr, wenn du ihn verwenden willst. Wenn du den Speicher mit malloc reservierst, wird er erst wieder freigegeben wenn DU ihn mit free( str); frei gibst. Eine andere Möglichkeit wäre es auch noch deiner Funktion einen leeren String zu übergeben, den die Funktion dann füllt, so könntest du auch noch zurückgeben ob die Eingabedaten korrekt waren, etc.
Das könnte dann so aussehen:

```
#include <stdio.h>
#include <string>

int serial_main( char, char *, char *);

int main() {
	char str[100] = "";
	char meinstring[] = "Diesen Text...";
	char zeichen = '7';
	if( serial_main( zeichen, meinstring, str))
		printf("Fehler in serial_main");
	else
		printf("%s", str);
}

int serial_main( char _zeichen, char *_string, char *_str) {
	strcpy( _str, _string);
	return 0;
}
```
Das wäre die elegantere Version.
Solltest du in deiner Funktion sprintf verwenden, schau dir mal die Funktion scprintf() an, sie hat denselben Syntay wie printf(), gibt dir jedoch zurück wie lange der String ist der mit printf() ausgegeben, bzw. mit sprintf() erzeugt wird. Mit dem return-Wert dieser Funktion kannst du bestimmen wieviel Speicher du reservieren musst.
Ansonst müsstest du sowas machen:

```
#include <cstdio>
#include <malloc.h>

char *mymain();

int main( int argc, char* argv[]) {
	char *test = mymain();
	printf("%s", test);
}

char *mymain() {
	char *str = (char *)malloc( sizeof(char)*5);
	str = "test";
	return str;
}
```
Nur zur verdeutlichung der Variante.

Schreib doch mal was du in deiner serial_main machen willst, dann würde ich mir etwas leichter tun.

mfg
uhu01


----------



## MartinFS (29. März 2005)

Hi,

statt der Deklaration in der main.cpp hatte ich eine serial.h Header Datei erstellt, wo genau die Zeile drinstand. War aber wohl nicht korrekt, denn mit der Deklaration in der main-Datei hat es nun prächtig funktioniert.

Habe mich für den leeren String entschieden, da der fürs erste am einfachsten zu implementieren war und auch am übersichtlichsten.

Danke   


... das nächste Problem kommt sicherlich bald.   


gruß,
MartinFS


----------



## uhu01 (29. März 2005)

Hy!

Könnte es sein das du bei der Deklaration in deinem Header das extern vor der Deklaration vergessen hast?

mfg
uhu01


----------



## MartinFS (29. März 2005)

Hi,

ja, war in der serial.h ohne "extern". Hat aber auch mit extern nicht funktioniert. Wieso auch immer... 
Die main-Klasse mit

```
extern char *serial_main( char argc, char *argv, char *rueckgstr );
```
funktioniert aber.

gruß,
MartinFS


----------



## Tobias K. (29. März 2005)

moin




> Die main-Klasse mit



Das hat ncihts mit Klasasen zu tun.


mfg
umbrasaxum


----------

