the Program to compile as shared library
string.h
/** string.h
*
* $Id$
*/
#ifndef STINRG_H_
#define STINRG_H_
#ifndef DEFAULT_BLOCKSIZE
// num. bytes of junks of memory to allocate from the heap
#define DEFAULT_BLOCKSIZE 128
#endif
#include <stdio.h>
#include <stdlib.h>
/** datatype to hold the character data */
struct string_t {
int memsize;
int length;
char *text;
int error;
};
typedef struct string_t string;
// function declarations
string str_redfile(FILE *file, int bs);
void str_dump(string *s);
unsigned long str_memsize(string *s);
#endif /* STINRG_H_ */
string.c
/** C example for reading file and allocating memory dynamically.
*
* Will read a file from disk while dynamically allocating memory.
*
* Example usage: ./exe [file-name]
*
* $Id$
*/
#include "string.h"
/** Read file from FILE pointer
*
* Reads data from FILE *file and dynamically allocates memory from the heap
* to store the read data. If memory allocation fails, the returned string
* struct's member error will equal to 1.
*
* If reading the file works, string.error will be 0.
*/
string str_redfile(FILE *file, int bs) {
int charsize = sizeof(char);
int charcount = 0;
int blocksize;
if (!bs)
blocksize = DEFAULT_BLOCKSIZE;
else
blocksize = bs;
int memsize = blocksize;
char *line = (char*) malloc(charsize * (memsize+1));
char *linep = line;
string l;
l.error = 0;
l.length = 0;
l.memsize = memsize;
l.length = charcount;
l.text = linep;
while (1) {
if(charcount > memsize) {
// reallocate memmory
memsize = memsize+blocksize;
char *al = (char*) realloc(linep, charsize * (memsize+1));
if (al == NULL) {
fprintf(stderr, "Error, out of memory.\n");
*line = '\0';
l.text = linep;
l.error = 1;
return l;
}
}
char c = fgetc(file);
//if (c == '\n' || c == '\r' || c == EOF) {
if (c == EOF) {
charcount--;
break;
}
// remember input char
*line = c;
*(line++);
charcount++;
}
*line = '\0';
l.text = linep;
l.memsize = memsize;
l.length = charcount;
return l;
}
/** return allocated memory of a string struct
*/
unsigned long str_memsize(string *s) {
return sizeof(string) + (s->memsize) + 1;
}
/** print struct string info
*/
void str_dump(string *s) {
if (s->error == 0) {
printf("memsize: %d\n", s->memsize);
printf("length: %d\n", s->length);
printf("error: %d\n", s->error);
printf("text: %.*s\n", 10, s->text);
printf("total: %lu\n", str_memsize(s));
} else
printf("Error: %d.\n", s->error);
}
test.c
/** test shared library
*
* an example how to use a shared library in a C program.
*
* $Id$
*/
#include "string.h"
/** main entry point
*/
int main(int argc, char **argv) {
// we need 1 argument, the file name
if(argc < 2) {
fprintf(stderr, "Usage: %s [file]\n", argv[0]);
exit(1);
}
// try to open the file
FILE *f = fopen(argv[1], "r");
if (f == NULL) {
fprintf(stderr, "Error: failed to open file: %s\n", argv[1]);
exit(2);
}
// allocate memory for storing the string and read contents
string l = str_redfile(f, 0);
// close file
fclose(f);
// check if reading worked
if (l.error != 0) {
fprintf(stderr, "Error: str_redfile() error: '%d'\n", l.error);
fclose(f);
exit(l.error);
}
// dump file infos
str_dump(&l);
// TODO: deallocate the memory
// free memory
//free(l.text);
exit(EXIT_SUCCESS);
}
compiling the shared library and the test program from a bash:
#!/usr/bin/env bash
#
# gcc, compile a shared object file
#
# This example shows how to compile a shared object for C with gcc on linux.
# required files: string.c, string.h test.
#
# $Id$
# configuration
bin=test
libname=string
v[0]=1; v[1]=0; v[2]=1;
# dynamic library
rm lib$libname* $bin
gcc -c -fPIC $libname.c -o $libname.o
gcc -shared -Wl,-soname,lib$libname.so -o lib$libname.so $libname.o
# create links for ld
#ln -s lib$libname.so lib$libname.so.${v[0]}
#ln -s lib$libname.so.${v[0]} lib$libname.so.${v[0]}.${v[1]}
#ln -s lib$libname.so.${v[0]}.${v[1]} lib$libname.so.${v[0]}.${v[1]}.${v[2]}
# compile executable
gcc $bin.c -o $bin -L. -l$libname
# run with proper LD_LIBRARY env variable, example:
# $ LD_LIBRARY_PATH=. ./test [path-to-file]
Running the executable. Make the newly compiled library available to ld through an environment variable.
$ LD_LIBRARY_PATH=. ./test [path-to-file]