■정적, 공유, 동적 라이브러리



라이브러리 : 자주 사용되는 기능들을 모듈 형태로 만들어 프로그램 유지보수 및 디버깅을 쉽게 할 수 있다.

  링크 단계에서 연결되거나 실행중 연결되기도 한다.




1. 정적 라이브러리 : 링크시에 포함되며 사이즈가 커지는 문제점이 발생


// mylib.h //

int sum(int a , int b);

int diff(int a, int b);


// mylib.c //

#include "mylib.h"

int sum(int a , int b)

{

return a+b;

}


int diff (int a, int b)

{

return a-b;

}


// main.c // 

#include "mylib.h"

#include <stdio.h>


int main()

{

int a, b;

a=100;

b=50;


printf("sum; %d\n", sum(a, b));

printf("diff: %d\n", diff(a,b));

return 0;

}


#gcc -c mylib.c                              =>mylib.o 오브젝트 파일 생성

#ar rc libmylib.a mylib.o                  =>아카이브 파일 생성
/*
r: replacement
c: create
*/
#gcc -o main main.c -L./ -lmylib       => -L은 라이브러리가 있는 경로, -l은 libmylib.a를 지정, 확장자 없이 라이브러리이름 넣어줍니다.

#./main                    




2. 공유 라이브러리

# gcc -fPIC -c ./lib/myfunc.c                                                             
/*
-fPIC : Position Independent Code
*/
# gcc -shared -W1,-soname,libmylib.so.1 -o libmylib.so.1.0.1 myfunc.o 
/*
-shared : 공유 라이브러리를 사용해서 링크
-W1 : warning level 1 에러시
-soname : 실제 만들 라이브러리인 libmylib.so.1.0.1 에 libmylib.so.1이라는 soname을 생성하여 나중에 
동적링크가 공유 라이브러리를 찾을때 soname인 libmylib.so.1를 찾아 링크 하도록 한다.
버전 관리를 융통성 있게 하기위함이고 gcc가 링크하는 파일명은 버전 정보가 없는 libmylib.so로 링크 파일 생성
*/
# cp libmylib.so.1.0.1 /usr/local/lib
# ln -s /usr/local/lib/libmylib.so.1.0.1 /usr/local/lib/libmylib.so
# gcc -o hello hello.c -L/usr/local/lib -lmylib
/*
libmylib.so를 찾으려면    -l옵션은 lib 를 기본적어로 붙여 찾는다. 그래서 -lmylib
*/
# export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:/usr/local/lib
# ./hello


3. 동적 라이브러리
// dylib.c //
#include<stdio.h>
#include<dlfcn.h>

int main()
{
        int a=100,b=50;
        void *handle;
        char *error;
        int (*result)(int,int);

        handle = dlopen("./lib/libmylib.so.2",RTLD_NOW);

        if(!handle)
        {
                printf("open error\n");
                return 1;
        }

        result = dlsym(handle, "sum");
        if((error = dlerror()) !=NULL)
        {
                fputs(error,stderr);
                return 1;
        }
        else
        {
                printf("sum : %d\n",result(a,b));
        }
        dlclose(handle);
        return 0;
}


# gcc -o dylib dylib.c -ldl


■파일

*파일 열기
// open.c //

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
int fd;
fd = open("hello.txt", O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
}

# cc open.c 
# ./a.out 
# ls -al hello.txt 
-rw-r----- 1 root root 0 2018-12-11 14:45 hello.txt
/*
파일이름 : hello.txt
파일이 없을 경우 생성
권한 640
*/



*파일 읽기

// fly.txt //
Fly me to the moon And let me play among the stars
Let me see what spring is like on Jupiter and Mars
In other words hold my hand
In other words darling kiss me
on Jupiter and Mars
In other words hold my hand

// read.c //
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

#define MAXLEN 80
int main()
{
int fd;
int readn  =0;
char buf[MAXLEN];
fd = open("fly.txt", O_RDONLY);
if(fd <0)
{
perror("file open error:");
return 1;
}
memset(buf, 0x00, MAXLEN);
while((readn=read(fd, buf, MAXLEN-1))>0)
{
printf("%s", buf);
    memset(buf, 0x00, MAXLEN);
}
}

# cc read.c 
# ./a.out 


*파일 쓰기

#include <unistd.h>
#include<stdio.h>
#include <fcntl.h>
#include <string.h>

int main()
{
        int fd;
        int i;
        int wdata=0;
        int wsize=0;
        fd = open("data.txt", O_CREAT|O_WRONLY);
        if(fd<0)
        {
                perror("file open error");
                return -1;
        }
        for(i=0; i<100; i++)
        {
                wdata=i*2;
                wsize=write(fd, (void*)&wdata, sizeof(int));
                printf("Write %d(%d byte)\n", wdata, wsize);
        }
        close(fd);
}



*구조체 데이터 파일 읽기, 쓰기


// addr_make.c //

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>

struct userInfo
{
  char name[28];
  int age;
  int sex;
  char hobby[28];
};

void makeUserInfo(struct userInfo *uinfo,
  char *name, // 이름
  int age,    // 나이
  int sex,    // 성 (남: 0, 여: 1)
  char *hobby) // 취미
{
  memset((void *)uinfo, 0x00, sizeof(struct userInfo));
  strcpy(uinfo->name, name);
  uinfo->age = age;
  uinfo->sex = sex;
  strcpy(uinfo->hobby, hobby);
}

int main()
{
  int fd;
  struct userInfo myAddrBook;
  fd = open("hello.txt", O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
  if (fd < 0)
  {
perror("file open error");
return 1;
  }

  makeUserInfo((void *)&myAddrBook, "user1", 19, 0, "programming");
  write(fd, (void *)&myAddrBook, sizeof(myAddrBook));

  makeUserInfo((void *)&myAddrBook, "user2", 22, 1, "playing games");
  write(fd, (void *)&myAddrBook, sizeof(myAddrBook));

  makeUserInfo((void *)&myAddrBook, "user3", 33, 1, "playing soccer");
  write(fd, (void *)&myAddrBook, sizeof(myAddrBook));

  close(fd);
  return 0;
}

# cc addr_make.c

// addr_read.c //
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>

struct userInfo
{
char name[28];
int age;
int sex;
char hobby[28];
};

int main()
{
int fd;
struct userInfo myAddrBook;
int dataSize;
fd = open("hello.txt", O_RDONLY);
if(fd<0)
{
perror("file open error");
return 1;
}
dataSize = sizeof(myAddrBook);
printf("User Info=================================\n\n");
while(read(fd, (void*)&myAddrBook, dataSize) == dataSize)
{
printf("name : %s\n", myAddrBook.name);
printf("name : %d\n", myAddrBook.age);
printf("name : %d\n", myAddrBook.sex);
printf("name : %s\n", myAddrBook.hobby);
printf("======================================\n");
}
close(fd);
return 0;
}
# cc addr_read.c 
# ./a.out 
User Info=================================

name : user1
name : 19
name : 0
name : programming
======================================
name : user2
name : 22
name : 1
name : playing games
======================================
name : user3
name : 33
name : 1
name : playing soccer
======================================



*파일 탐색

off_t lseek(int fd, off_t pos, int origin);


origin 값 : SEEK_CUR : pos가 0 -> 현재위치값 else -> 현 위치값 + pos

   SEEK_END : pos가 0 -> 파일의 끝지점 else-> 끝 위치값 + pos

   SEEK_SET : post 가 0 -> 파일의 시작지점 else -> 시작 위치값 + pos


// lseek.c //

int main(int argc, char **argv)

{

int fd;

int i, buf;

fd = open("num.dat", O_RDWR|O_CREAT);

if (fd < 0)

{

perror("error : ");

exit(0);

}

for (i = 1000; i < 1010; i++)

write(fd, (void *)&i, sizeof(i));


lseek(fd, 0, SEEK_SET);

read(fd, (void *)&buf, sizeof(i));

printf("%d\n", buf);


lseek(fd, 4*sizeof(i), SEEK_SET);

read(fd, (void *)&buf, sizeof(i));

printf("%d\n", buf);


}


# cc lseek.c 

# ./a.out 

1000

1004


+ Recent posts