라이브러리??

익명 사용자의 이미지

안녕하세요?? 제 글을 읽어 주시는 님들.. 꾸벅~~ *^^*

그냥 곧바로 질문 들어가면 예의에 어긋날까요??

라이브러리를 공부하다 궁금해서 질문을 드립니다.

라이브러리에는 세 가지의 종류가 있다고 하더군요..

정적, 공유, 동적..
정적은 프로그램이 실행전에 메모리에 적재된다고 하던데.. 맞습니까?
맞다면 목적파일의 주소가 메모리에 적재되는 거겠죠? 이거.. 맞습니까?
주 메모리에 라이브러리가 들어간다면 절대주소로 들어가서
파일을 실행시킬때 그 라이브러리를 찾아간다는 겁니까?
그런데.. 이거 왜 사용하는 거죠? <--요게 가장 중요한 질문입니다..

공유는 프로그램 실행전에 링크가된다고 하던데.. 이건 무슨 말입니까?
그리고 공유 라이브러리는 도대체 무엇 때문에 사용하는 겁니까?
왜 이게 정적을 몰아내고 대체되고 있는거죠??

동적 라이브러리.. 이건 정말 이해가 안 가더군요..
공유와 동적을 구분하는 경계선은 무엇입니까?
공유가 있는데 굳이 동적을 사용하는 이유는 무엇입니까?

라이브러리에 대한 사항을 찾아 보았는데, 제가 보기엔 조금 난해하더군
요.
무엇보다도 '왜?'에 대한 것이 없었습니다.
정적이야 주 메모리에 라이브러리를 상주(아니. 그 주소를 상주시키나
요?)
시키기 때문에 요즘처럼 시스템이 빠른 상황에서는 그 라이브러리 탐색 시
간이
거의 무시되는 상황에서 오히려 메모리 낭비니까 사용이 줄어든다고 한다
면,
공유와 동적은 도대체 무슨 이유때문에 그것을 사용합니까?
그것을 정말 알고 싶습니다.

질문을 요약하면 다음과 같습니다.
1. 정적 라이브러리는 라이브러리의 오브젝트 파일의 주소를 메모리에 적
재시키는가?

2. 공유 라이브러리는 어떻게 링크를 시키는가? 프로그램 실행전이라는
말은 정적과 같은 의미인가? 다르다면 어떻게 다른 것인가?

3. 동적 라이브러리는 언제 링크를 시키는 것인가?
#include 의 dlopen()을 부를때 컴파일 시키고 링크를 시키는
가? 공유와는 또 어떻게 다르다는 것인가? 어떤 의미에서?

4. 도대체 정적과 공유와 동적은 왜 사용하는가?

이상과 같습니다. 나름대로 정리하려구 노력한거구요..
여러분들의 답변을 기다립니다. 감사합니다. 꾸벅~~

익명 사용자의 이미지

컴파일할때 라이브러리를 추가할 수 있죠.
-> 이건 프로그램이 돌아가려면 꼭 필요하기 때문에 그러겠죠..

때로는 프로그램 내에서 필요에 따라 라이브러리를 로딩할 수 있습니다.
-> 상황에 따라서는 없어도 되는 라이브러리가 될 수도 있죠.. 그 반대의
경우도 가능하구요.

공유메모리의 경우는 저도 잘 모르겠군요..(무책임.. 퍽!)

C에서는 잘 모르겠지만 C++로 들어가서는 동적으로 사용하는 방법도 많이
쓰입니다. 그만큼 스타일 자체가 분산객체를 사용하니까요..

뭐.. 이정도의 개념만.. ^^( 틀릴수도 있다는.. 우직!)

익명 사용자의 이미지

; 정적은 프로그램이 실행전에 메모리에 적재된다고 하던데.. 맞습니까?
; 맞다면 목적파일의 주소가 메모리에 적재되는 거겠죠? 이거.. 맞습니까?
; 주 메모리에 라이브러리가 들어간다면 절대주소로 들어가서
; 파일을 실행시킬때 그 라이브러리를 찾아간다는 겁니까?
; 그런데.. 이거 왜 사용하는 거죠? <--요게 가장 중요한 질문입니다..

질문에 문제가 있군요.
메모리의 절대주소가 아닙니다. 메모리에서 절대주소는 VMM시스템
하에서는 알수가 없습니다. OS만 알고 있죠.
그리고 lib는 컴파일 시점이 중요합니다. 컴파일 시점에서
link되느냐(실행프로그램에 포함) 아니냐에 따라서 정적과 동적으로
나누어 집니다.

그리고 동적과 공유로는 특별히 나누지 않습니다.
다만 동적 lib를 공유방식으로 사용하느냐. 독립적으로 사용하느냐는
메모리에 load할때(프로그램지정, 환경설정) 결정되어 진다고 할수
있죠. "man dlopen"을 참조 하십시요.

; 공유는 프로그램 실행전에 링크가된다고 하던데.. 이건 무슨 말입니까?
; 그리고 공유 라이브러리는 도대체 무엇 때문에 사용하는 겁니까?
; 왜 이게 정적을 몰아내고 대체되고 있는거죠??

뭔가를 오해하고 있는 것 같습니다. 단지 많은 공통 lib가 shared lib로
변경된다고 그것이 모든 것을 의미하지는 않습니다. 그리고 실행전이
아니라 실행시에 link됩니다. 아마 공유영역에 먼저 올라(load)갈수도
있느니까 실행전으로 오해를 하신듯.
공유 LIB를 사용하는 이유는 loading Time, compile된 program size,
사용상의 특수 목적(동일 함수를 환경에 따라 달리 적재 *),
Version up시 일부 모듈만 변경 등의 많은 이유로 사용 됩니다.
특히 lib Version up 정적일때는 그것을 사용하는 모든 프로그램을 모두
재 compile 해야하는데 시스템 기본 Lib라면 거의 불가능에 가깝다고
해야하지요. 하지만 공유 lib라면 간단하게 lib Version up이
가능해 지죠. lib를 사용하는 모든 프로그램을 컴파일할 필요없죠.
그레서 공유 lib를 사용하는 겁니다.
(속도가 느리다는 단점에도 불구하고)

1. 정적 라이브러리는 라이브러리의 오브젝트 파일의 주소를 메모리에 적
재시키는가?
--> 컴파일시점에 실행프로그램에 link됩니다.

2. 공유 라이브러리는 어떻게 링크를 시키는가? 프로그램 실행전이라는
말은 정적과 같은 의미인가? 다르다면 어떻게 다른 것인가?
--> strace나 truss(BSD, SUN)로 실행프로그램을 한번 추적 해보세요.
--> 실행시점이고, 단지 pre load되었다고나 할까요 ?

3. 동적 라이브러리는 언제 링크를 시키는 것인가?
#include 의 dlopen()을 부를때 컴파일 시키고 링크를 시키는
가? 공유와는 또 어떻게 다르다는 것인가? 어떤 의미에서?
--> 공유라는 말과 동적이라는 말사이에서 혼란이 있네요.
--> 정확하게 말한다면 "동적" lib를 여러 프로그램들이 "공유"한다.
라고 말 할 수 있는데요. 오해를 한듯.....
--> 위의 문장은 의미를 전혀 이해 할수 없음.

4. 도대체 정적과 공유와 동적은 왜 사용하는가?
--> 위의 답변으로 갈음함.

첨언을 하면 시스템의 메뉴얼을 조금더 주의깊게 읽어 보세요. 그기에 원
하는 답이 있습니다.

참고.
(동일 함수를 환경에 따라 달리 적재 *)
ex) 환경에 따라 Oracle을 쓰기도 하고, informix를 쓰기도 하는데.
프로그램은 하나로 작성하고 싶다면 (DB, Table은 모두 동일)
oracle을 사용한 DSO File하나와 informix를 사용한 DSO File하나를
가지고서 상황에 따라서 원하는 모듈을 올리면 되겠지요.
물론 mysql이 필요하다면 mysql DSO File 하나 만들면 되겠지요.
구체적인 예로 아파치 웝서버에서 사용예를 볼수 있습니다.

man dlopen 중에서 ....
라이브러리에 있는 외부 참조는 이 라이브러리의 의존관계 목록에 있는 라
이브러리와 전에 RTLD_GLOBAL 플래그로 열린 다른 라이브러리를 사용하는
것으로 해결된다. 만약 실행 파일이 "-rdynamic" 플래그로 연결되었다면,
실행 파일에 있는 전역 심볼은 동적으로 탑재된 라이브러리의 참조를 해결
한다.

flag는 반드시 RTLD_LAZY - 동적 라이브러리의 코드가 실행되어 정의되지
않은 심볼을 해결하는 것을 의미 - 또는 RTLD_NOW - dlopen 이 반환되기
전에 정의하지 않은 모든 심볼을 해결하는 것을 의미 - 이어야만 한다. 그
리고 이 과정이 수행되지 않으면 실패할 것이다. 추가적으로, RTLD_GLOBAL
은 라이브러리안에 정의된 외부 심볼이 뒤이은 라이브러리가 탑재되는 것
이 가능하게 할 경우에 flag와 OR 될 수 있다.

만약 라이브러리가 _init이라는 루틴에 전달될 경우, 라이브러리에 있는
코드는 dlopen이 반환되기 전에 수행될 것이다. 만약 같은 이름의 라이브
러리가 dlopen()으로 두 번 적재된다면 같은 파일 핸들을 리턴한다. dl 라
이브러리는 동적 파일 핸들의 링크 수를 관리한다. 그래서 동적 라이브러
리가 dlopen에 의해 성공적으로 호출된 만큼 dlclose을 호출할 때까지 할
당한 것을 해제하지 않는다.

만약 dlopen이 어떤 이유에서라도 실패를 한다면 NULL을 반환한다. dl 루
틴 (dlopen, dlsym, dlclose) 에 의해 발생한 가장 최근의 에러를 보기 위
해서는 dlerror()을 호출해야 한다. dlerror은 초기화 이후 또는 이 함수
가 마지막으로 호출 (연속적으로 이 함수가 두번 호출되면 두번째 호출의
반환값은 항상 NULL이다.) 된 후 아무런 에러가 발생하지 않았다면 NULL
을 반환한다.

dlsym은 dlopen에서 리턴된 동적 라이브러리의 핸들과 null로 끝나는
symbol 이름을 취하고 이 심볼의 적재된 주소를 반환한다. 만약 심볼을 찾
지 못하면, NULL을 반환한다; 그러나 dlsym에 의해 발생한 에러를 정확히
알아보는 방법은 dlerror에 의한 결과값이 NULL이 아닌 경우 그 값을 검사
하는 것이다. 이렇게 하는 이유는 심볼의 값이 실제로 NULL이 되는 경우
가 있기 때문이다. 그리고 dlerror이 다시 호출될 때에는 NULL을 반환하
기 때문에, 필요하다면 dlerror의 결과값를 저장해야만 한다.

dlclose은 동적 라이브러리 핸들인 handle에 대한 참조계수를 하나 감소시
킨다. 만약 참조계수가 0이 되고 다른 어떤 적재된 라이브러리들이 적재
를 취소하고자 하는 동적 라이브러리에 있는 심볼을 사용하지 않으면, 동
적 라이브러리는 적재가 취소된다. 만약 동적 라이브러리가 _fini라는 루
틴에 전달될 경우, 라이브러리의 적재가 취소되기 바로 전에 이 루틴이 호
출될 것이다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.