'Programming'에 해당되는 글 7건

  1. 2013.03.23 [번역] A-Z of Programming Languages: Scala 1
  2. 2009.01.04 [리눅스 라디오 프로그램 제작기] 2. kbs 온에어 재생 7
  3. 2009.01.04 [리눅스 라디오 프로그램 제작기] 1. 개요 & 개발 환경 구축 2
  4. 2008.12.14 [Qt] 어플리케이션 다국어 지원
  5. 2008.12.14 [Qt] 프로퍼티 사용하기
  6. 2008.12.14 [Qt] signal과 slot 사용하기
  7. 2008.11.22 [PHP] OCI8을 사용하여 오라클 DB 접근하기

[번역] A-Z of Programming Languages: Scala

원문 : http://www.computerworld.com.au/article/315254/a-z_programming_languages_scala/

트위터와 링크드인 모두 스칼라를 사용하지만, 웹 2.0 스타트업들의 총아인 스칼라는 대기업에서도 널리 사용된다. 컴퓨터월드는 마틴 오더스키와 얘기를 나눴다.


컴퓨터월드는 프로그래밍 언어 세계로의 연속된 조사를 하고 있다. 이미 해스켈, 얼랭, (역시 JVM 에서 실행되는) 클로저 등의 몇 가지 다른 함수형 언어를 살펴보았다.


이번 인터뷰에서는 마틴 오더스키와 스칼라에 관해 이야기했다. 우리는 스칼라를 개발자들이 써봤으면 하는 6가지 스크립트 언어 중 하나로 꼽은 바 있다. 스칼라는 자바 가상 머신에서 돌아가는 새로운 언어 중 하나이며, 점점 인기를 얻고 있다.




트위터 개발자 중 한 명은 스칼라가 그 새로운 웹 2.0 스타트업의 선택 받은 언어가 될 수 있다고 말했다. 링크드인 또한 스칼라를 쓴다. 소니 픽쳐스, EDF, SAP을 비롯한 많은 대기업에서도 사용한다. 마틴 오더스키는 스칼라의 역사, 미래, 그리고 무엇이 스칼라를 매우 흥미롭게 만들었는지에 관해 얘기해줬다.


왜 이름을 스칼라라고 지었나?

아주 작게 시작하지만 먼 길을 갈 수 있다는 점에서 확장 가능한scalable 언어라는 뜻이다. 새로 접한 사람들에게는 스크립트 언어처럼 보인다. 실제로 지난 2년 동안 자바 스크립트 언어 시합인 JavaOne ScriptBowl에서 경쟁하도록 초대를 받기도 했다. 그러나 스칼라는 진짜로 스크립트 언어는 아니다 - 그것은 스칼라의 주요 특성이 아니다. 사실, 스칼라는 자바로 할 수 있는 모든 것을 표현할 수 있고, 자바의 능력을 넘어서 대규모 시스템에 필요한 많은 것들을 스칼라가 제공할 수 있다고 믿는다. 설계 기준 중 하나는 매우 작은 프로그램에서부터 시작해서 거대한 시스템에 이르기까지 모두 유용하고, 그 과정에서 구조를 바꿀 필요가 없는 언어를 만들고 싶다는 것이었다.


무엇때문에 스칼라를 개발하게 되었나?

90년대 중반에 자바 언어와 컴파일러 개발에 참여하게 됐다. 필립 와들러라는 연구원과 함께 일하게 되었고, 우리는 나중에 제너릭 자바(GJ)가 되고 그 후 자바 버전 5가 된 피자를 개발했다. 도중에 나는 javac 컴파일러를 작성했다. GJ를 위한 그 컴파일러는, 우리의 확장판이었는데, 선이 GJ 언어 구성물을 자바에 채택하기로 결정하기 오래 전에 표준으로 채택되었다 - 컴파일러를 먼저 채택한 것이다.


10년 전에 스위스로 옮겼을 때, 더 기본적인 주제들을 연구하기 시작했다. 함수형 프로그래밍과 객체 지향 프로그래밍을 유용하게 조합할 수 있을지를 확인하기 위해 몇 가지 실험적인 연구를 했다. 95,6년에 피자로도 이미 해봤지만, 그건 절반의 성공이었다. 왜냐하면 다음어지지 않은 부분이 많았기 때문인데, 모두 그 당시에 자바를 기본 언어로 사용한 것과 관련이 있었다. 자바는 그리 변경하기 쉽지 않았다. 그래서 2000년 경부터 시작해서 EPFL(국립 로잔 공과대학)에 있는 내 그룹과 함께, 자바와 함께 쓸 수 있으면서도 객체 지향과 함수형 언어 테크닉을 유용하게 섞어 쓸 수 있는 언어를 개발했다.


이 중 첫번째는 Funnel이라 불렀고, 두번째가 스칼라였다. 두번째 실험은 아주 잘 돼서, 실험 단계는 접고 스칼라를 사람들이 기댈 수 있는 실제 언어로 만들기로 했다. 거친 면을 좀 다듬고, 문법을 약간 바꾸고, 스칼라와 스칼라 툴이 널리 쓰일 수 있다는 것을 확신하기 위해서 스칼라 툴을 스칼라로 다시 작성했다. 그 후 2006년에 스칼라 버전 2를 출시했다. 스칼라는 그 때부터 급속하게 인기를 얻고 있다.


객체 지향과 함수형 언어 테크닉을 결합하는 주요 이점은 뭔가?

둘 다 많은 것을 제공한다. 함수형 언어는 강력한 조합을 제공하기 때문에 간단한 부분들을 가지고 흥미로운 것들을 만들 수 있다 - 함수들은 프로그램의 요소들을 흥미로운 방법으로 다른 요소들과 결합한다. 이와 관련된 함수형 프로그래밍의 이점은 함수들을 데이터로 간주할 수 있다는 점이다. 거의 모든 프로그래밍 언어의 전형적인 데이터 타입은 "정수형int"이다. 정수형 값은 함수 내부를 포함한 어디에서도 선언할 수 있고,  그것을 함수로 넘기고, 함수로부터 리턴하거나 필드에 저장할 수도 있다. 함수형 언어에서는 함수에 대해서도 똑같이 할 수 있다. 함수를 다른 함수 내에서 선언하고, 함수를 함수로 넘기거나 리턴 받을 수도 있고 필드에도 저장할 수 있다. 이런 특성은 여러분 자신의 제어 구조를 만드는 데, 매우 고수준의 라이브러리를 정의하거나 새로운 DSL 만드는 데 강력한 방법을 제공한다.


반면, 객체 지향 프로그래밍은 시스템 컴포넌트를 구조화하고 복잡한 시스템을 확장하거나 개선하는 데 강력한 방법들을 제공한다. 상속과 조합aggregation은 네임스페이스를 만들고 조직화하기 위한 유연한 방법을 제공한다. IDE(통합 개발 환경)에서 어떤 지점에서 호출할 수 있는 모든 메서드를 팝업 메뉴로 제공하는 컨텍스트 도움과 같은 유용한 툴 지원이 있다. 


두 가지 언어가 각각 존재하는 듯한 느낌을 주지 않고 하나의 언어로 결합하는 게 어려운 일이었다.


그 도전의 가장 중요한 부분이 무엇을 뺄 것인지를 결정하는 것이었을 것 같은데?

맞다. 만약 각 언어의 스타일을 모두 가져와 결합했다면, 중복된 점이 많아졌을 것이고 단지 서로 영향이 거의 없는 두 개의 서브 언어가 됐을 것이다. 한 쪽의 구성물을 다른쪽의 구성물과 동일시하는 게 어려운 점이었다. 예를 들어, 함수형 프로그래밍 언어의 함수값function value는 객체 지향 언어의 객체에 해당한다. 근본적으로 그것을 "apply" 메서드가 있는 객체라고 볼 수 있다. 결과적으로 우리는 함수값을 객체로 모델링할 수 있었다.


또다른 예는 함수형 언어의 대수algebraic 데이터 타입들을 객체 지향 언어에서는 클래스 계층으로 모델링될 수 있다는 것이다. 또한, 자바에 있는 스태틱 필드와 메서드를 제거하고 대신 싱글턴 객체의 멤버로 모델링했다. 그 외에도 한 언어의 구성물을 다른 언어에 존재하는 것과 매칭시켜서 합친 경우가 많이 있다.


스칼라를 개발하면서 맞닥뜨린 전체적으로 가장 큰 도전은 뭐였나?

컴파일러 기술을 개발하는 것이 확실히 어려웠다. 흥미롭게도 그 어려움은 객체 지향 언어에서보다 더했다. 진보된advanced 스태틱 타입 시스템을 갖춘 객체 지향 언어는 매우 드물었고, 그들 중에 하나도 주류가 아니었다. 스칼라는 자바나 비슷한 언어보다 훨씬 더 표현적인expressive 타입 시스템을 갖고 있어서, 구성 요소 조합을 위해 우아한 타입 개념과 프로그래밍 관념abstraction을 개발함으로써 새로운 영역을 개척break new ground해야 했다. 이것은 매우 어려운 작업이 되었고 또한 새로운 연구 결과도 나왔다.


또다른 어려운 부분은 상호 운용성interoperability과 관계가 있었다. 우리는 상호 운용이 매우 잘 되기를 원했고, 따라서 자바의 모든 것을 스칼라로 매핑해야 했다. 자바 라이브러리의 거대한 부분을 충실하게 매핑하기를 원했던 것과, 동시에 자바 언어의 모든 구성물과 중복을 피하는 것 사이에 항상 긴장이 있었다. 그것은 지속적이고 도전적인 엔지니어링 문제였다. 전체적으로 그 결과에 매우 만족하지만, 할 일이 참 많았다. 


포럼에 스칼라의 효율성과 확장성에 대해 긍정적인 평가도 많지만, 자주 언급되는 다른 점은 매우 재미있게 쓸 수 있는 언어라는 것이다. 이것도 스칼라를 설계할 때의 목표 중 하나였나?

물론이다. 동료들과 나는 코드를 작성하느라 많은 시간을 보내서 즐겁게 프로그래밍할 수 있는 것을 원했다. 그건 아주 분명한 목표였다. 우리는 규약이 많은high-protocol 전통적인 언어에 있는 상투적인 것들incantations을 가능하면 많이 없애기를 원했고, 개발자들이 원하는 대로 모델링할 수 있도록 스칼라에 높은 표현력을 주고 싶었다. javac를 개발할 때 자바 프로그래밍을 많이 했는데 자바 프로그래머들이 얼마나 쓸데 없는 작업을 많이 해야 하는지를 깨달았다. 같은 프로그램을 스칼라로 개발하면 라인 수가 대체로 2~3배 적은 것을 볼 수 있다. 많은 상투어boilerplate를 쓸 필요없고, 게다가 훨씬 더 재미있다.


이것은 우리가 개발자들에게 주는 강력한 도구이지만, 두 가지 면이 있다. 개발자들에게 많은 자유를 주지만 잘못된 사용을 피해야할 책임도 준다. 철학적으로 그게 자바와 스칼라의 가장 큰 차이점이라고 생각한다. 자바는 상당히 제한된 개념을 갖고 있어서 어떤 자바 프로그램이라도 다른 자바 프로그램과 좀 비슷해 보이고, 이는 프로그래머들을 교체하기swap 쉽도록 한다는 주장이 있다. 스칼라는 매우 표현적인 프로그래밍 언어이기 때문에 이러한 균일성은 없다.


스칼라 프로그램을 여러 가지 방법으로 개발할 수 있다. 자바로 시작한 프로그래머들에게 좋도록 자바처럼 짤 수도 있다. 이는 프로그래밍 그룹이 스칼라로 넘어오기 쉽도록 하고, 프로젝트의 리스크가 낮도록 한다. 그들은 중요하지 않은 부분부터 시작한 후 적당하다고 생각하는 속도로 범위를 넓힐 수 있다.


하지만 스칼라 프로그램을 완전히 함수적인 방법으로 짤 수도 있고 이런 프로그램들은 전형적인 자바 프로그램들과 전혀 달라 보일 수 있다. 종종 훨씬 더 간결하다. 이게 주는 이점은 고수준의 라이브러리나 스칼라에 내장된 DSL처럼 자신만의 관용구idioms를 개발할 수 있다는 것이다. 전통적으로, 똑같은 효과를 얻으려면 몇 가지 다른 언어나 설정 기법을 혼합해야 했다. 따라서 궁극적으로는 스칼라의 단일 언어 접근법이 더 간단한 해결책을 내놓게 할 수도 있다.


스칼라를 쓰기를 원하는 자바 개발자들에게는 학습 부담(learning curve)이 작겠지만 PHP나 파이선, 루비와 같이 동적 규율을 갖춘 동적 언어로 일하는 데 익숙한 프로그래머들이 배우기에는 어떨까?

확실히 자바나 닷넷 개발자들이 스칼라를 배우기 가장 쉽다. 다른 커뮤니티들에 관해서라면 걸림돌stumbling blocks은 언어 자체와는 별 관련이 없고, 패키징하는 법과 자바에 특정한 도구를을 구성set up하는 법이다. 이런 것들을 어떻게 구성하는지를 한 번 배우면, 언어 자체를 배우는 데는 어렵지 않을 것이다.


트위터가 스칼라를 쓰고 있는 것은 어떻게 생각하나? 이런 인지도 높은 사이트가 스칼라를 쓰는 게 스칼라 언어의 개발에 도움이 되나?

그것은 굉장한 소식이었다. 그들이 스칼라로 옮겨갔다는 것과 스칼라가 잘 쓰이고 있다는 게 기쁘다. 트위터는 외적인 성장을 잘 버텨왔고, 스칼라로 교체하기 전보다 더 견고해진 것 같다. 이는 스칼라에 좋은 증거testament라고 생각한다. 트위터처럼 인지도 높은 사이트가 새로운 언어를 채택하는 것은 그 언어에 매우 신랄한 테스트가 된다. 만약 그 언어에 커다란 문제들이 있다면 아마도 더 빨리 발견될 것이고 두드러지게 강조될 것이다.


스칼라를 채택하는 다른 잘 알려진 회사들도 많이 있다. 소니 픽쳐스 이미지웍스는 미들티어 소프트웨어 개발에 스칼라를 쓰고 유럽 최대의 에너지 회사인 EDF는 영업 부문에서 계약 모델링에 스칼라를 쓰고 있다. SAP와 지멘스 그들의 오픈 소스 기업 소셜 메시징 실험Enterprise Social Messaging Experiment(ESME) 도구에 스칼라를 쓰고 있다. 이는 많은 예 중에 단지 셋일 뿐이다.


트위터 개발자 중 한 명인 알렉스 페인은 스칼라가 그 새로운 웹 스타트업이 선택하는 언어가 될 수 있고, 매우 인기 있지만 스칼라 만큼 효율적이지 않은 파이선이나 루비 같은 언어보다 더 쓰일 수 있다고 했다. 이에 동의하나? 그리고 스칼라를 개발할 때 웹 2.0 스타트업들을 염두에 두었나?

스칼라가 이 영역에 적합다다고 본다. 이를 깨달은 것은 트위터뿐은 아니고 링크드인도 스칼라를 사용한다.


스칼라가 거기에 제공하는 것은 애자일한 언어를 쓰면서 견고한 고성능 플랫폼 - 자바 가상 머신(JVM) 위에 구축할 수 있는 능력이라고 생각한다. 자이선, J루비, 그루비, 클로저 등도 있지만 이것들은 모두 JVM에서 실행되는 동적 타입 언어이다.


결국 질문은 정적 타입 설정이 더 편하냐는 점에 도달하는데, 많은 에러를 일찍 잡을 수 있기 때문에 그럴 수도 있고, 리팩토링을 위한 안전망을 제공한다는 점에서, 또는 성능에 도움이 된다는 점에서 그럴 수도 있다. 혹은 메타 프로그래밍으로 화려한 것들을 하고 싶어서 완전한 동적 언어를 원할 수도 있다. 궁극적으로 그런 선택에 도달한다. 만약 정적 타입 언어를 원한다면 현재는 스칼라가 가장 좋은 선택이라고 생각한다.


스칼라의 특징 중에서 가장 좋아하는 것을 하나 꼽는다면?

가장 좋아하는 특징 하나를 고를 수 없을 것 같다. 오히려 스칼라의 특징들이 함께 작동하는 방식을 선택하겠다. 예를 들어, 고차 함수high-order functions가 어떻게 객체들과 추상 타입들과 함께 혼합되는지, 또는 스칼라에서는 함수가 상속될 수 있기 때문에 액터가 어떻게 가능해졌는지이다. 스칼라에서 가장 흥미로운 디자인 패턴들은 명확히 객체 지향과 함수형 언어 아이디어 사이의 상호 작용으로부터 유발된다.


앞으로 스칼라가 지향하는 것은?

단기적으로 다음 릴리즈인 스칼라 2.8을 위해 열심히 작업 중인데, 무엇보다도 고성능 배열 연산, 그리고 빠른 영속적인 데이터 구조를 가지고 컬렉션 라이브러리를 재정의하는 데 집중하고 있다. 올해 가을[북반구 기준으로]이면 나올 것이다.


그 후 장기적으로 동시성과 병행성 쪽에서 흥미로운 기회를 보고 있어서 멀티 코어 프로세서와 다른 병행 시스템에서 프로그래밍하는 데 새로운 방법을 찾고 있다. 스칼라는 동시성을 표현하는 고수준 방법을 제공하는, 유명한 액터 시스템을 갖고 있기 때문에 이미 여기에 유리한 점이 있다. 예를 들면 트위터의 메시지 큐에 사용된다. 재미있는 점은 스칼라에서의 액터는 언어 기능이 아니고 순수하게 스칼라 라이브러리로 구현됐다는 것이다. 따라서 이는 스칼라의 유연함에 대한 좋은 증거가 된다. 라이브러리에 적절한 기본 요소primitives와 관념abstractions을 포함시킴으로써 어플리케이션 프로그래머들에게 언어 기능으로 보이는 것들을 프로그래밍할 수 있다.


액터에 대한 작업이 데이터 병행성과 스트림 프로그래밍 등의 다른 동시성 관념concurrent abstractions에도 효과가 있기를 기대한다. 다른 종류의 병행성과 동시성은 다른 도구를 필요로 할 것이기 때문에, 미래에는 아마도 멀티 코어를 제대로 쓰기 위해 몇가지 동시성 관념이 필요할 것이라고 본다. 스칼라의 라이브러리 기반 접근이 여기에 적합하다고 보는데, 스칼라 클래스와 객체로 구현된 개념들을 섞고 매칭시켜서, 모든 것을 언어와 컴파일러에 넣는 것보다 빠르게 나아갈 수 있게 하기 때문이다. 다음 4,5년은 이 작업으로 바쁠 것 같다.

[리눅스 라디오 프로그램 제작기] 2. kbs 온에어 재생

리눅스용 라디오 프로그램의 첫 단계로 kbs 라디오 온에어를 재생하는 프로그램을 만들었다. kbs를 먼저 선택한 이유는 이전 글에서도 말했듯이 kbs 온에어는 로그인이 필요하기 때문이다. 텍스트 모드로 작동하며 채널, kbs 사이트 아이디, 패스워드를 argument로 주어 실행하면, 온에어를 재생해주는 간단한 프로그램이다.

프로그램은 크게 두 가지 부분으로 나뉘어 진다. 먼저 kbs 사이트에 로그인한 후 mms url을 얻어오는 부분, 그리고 mms url을 재생하는 부분이다. 이 중에서 mms 재생하는 부분은 GStreamer 매뉴얼의 playbin 항목을 참고했다. 볼륨 조절이나 정지/재생 기능은 일단 고려하지 않고 단순히 재생하는 데만 초점을 맞추었기 때문에 예제 코드를 거의 그대로 갖다 썼다.

kbs 사이트에 로그인하는 부분은 조금 삽질이 필요했다. 파이어폭스 확장 기능인 httpfox를 사용하여 로그인부터 온에어 url이 전송되는 부분까지 거쳐 가는 페이지들을 추적했다. 서버 단에서 일어나는 일들을 정확히 알 수 없었기 때문에 httpfox에서 보이는 http request/response를 보고 추측해야 했다. 이렇게 알아낸 것들을 바탕으로 libsoup 라이브러리를 사용하여 http request를 보내고 response를 받으며 mms url이 나올 때까지 계속해 갔다. 그리고 이 과정에서 쿠키에 저장되는 정보가 있는데 request를 보낼 때 설정해 주어야 했다. 이런식으로 로그인부터 mms url을 얻어오는 데 성공하기 까지 며칠은 걸린 것 같다. libsoup 튜토리얼이라도 있었으면 좀 쉽게 했을텐데...

어쨌듯 온에어를 재생하는 데 성공했으니 이제 다음으로 GUI를 붙여 봐야 겠다.





소스 설명
get_url.h, get_url.c : kbs 사이트에 로그인하고 mms url을 얻어오는 코드(libsoup 사용)
player.h, player.c : mms url을 재생하는 코드(GStreamer 사용)
main.c : 말 그대로 메인

이번에 사용한 GStreamer 코드는 얼마되지 않는다. 위에서도 말했듯이 playbin 코드를 많이 참고하였고, 필요한 부분만 뽑았기 때문에 간단하다.

libsoup 사용 부분은 조금 길긴 하지만 HTML 폼 파라미터 처리가 필요하고 http request를 여러 번 주고 받아야 되어서 길어졌을 뿐, 실제로 사용한 libsoup 함수는 몇 가지 안된다.

soup_session_sync_new();            // soup session을 생성
soup_message_new();                   // http request를 생성
soup_message_set_request();         // 폼 데이터와 함께 POST request를 보낼 때 사용
soup_session_send_message();     // http request를 보냄
soup_message_headers_append(); // http 헤더 셋팅(kbs 사이트에 referer를 체크하는 부분이 있어 사용했다.)
soup_cookies_to_request();            // request에 쿠키를 포함할 때 사용



컴파일 및 실행 방법
※ 이전 글에서 설명한 개발 라이브러리들이 설치되어 있어야 컴파일이 된다.
young@y0un5:~/Study/onair$ tar xzvf onair.tar.gz
./Makefile
./get_url.c
./get_url.h
./main.c
./onair
./player.c
./player.h
young@y0un5:~/Study/onair$ ls
Makefile  get_url.c  get_url.h  main.c  onair  onair.tar.gz  player.c  player.h
young@y0un5:~/Study/onair$ make
gcc -o onair main.c get_url.c player.c `pkg-config --cflags --libs libsoup-2.4 gstreamer-0.10`
young@y0un5:~/Study/onair$
young@y0un5:~/Study/onair$ ./onair [채널 - 1AM, 2FM 등] [kbs 사이트 ID] [패스워드]
[DEBUG] Dest URL : L_2FM
[DEBUG] got onair url : mms://211.233.92.42/L_2FM?[ID]
[DEBUG] now play mms://211.233.92.42/L_2FM?[ID]




[리눅스 라디오 프로그램 제작기] 1. 개요 & 개발 환경 구축

요즘 예전부터 생각해 왔던 리눅스용 라디오 프로그램을 만들고 있다. 나중에 또 다시 삽질하는 것도 방지하고 혹시나 참고하실 분들이 있을까 싶어 여기에 차근차근 정리해 가면서 진행하려고 한다.

개발 목적
이 프로젝트의 목적은 간단하다. 리눅스에서 간편하게 쓸 수 있는 GUI 라디오 프로그램을 만드는 것이다. kbs의 콩, mbc의 미니, sbs의 고릴라 등의 리눅스 버전이라 생각하면 되겠다. mbc, sbs 등 스트리밍 url이 공개되어 있고 로그인하지 않아도 되는 것들은 바로 그 url을 재생하고 kbs처럼 로그인이 필요한 것은 사이트에 직접 접속하여 스트리밍 url을 얻어와 재생하는 방식으로 구현할 것이다. (사실 이 프로그램을 만들기로 결심한 것은 kbs 때문이다. 공개된 url은 없고, 사이트에서도 온에어 링크가 잘 작동이 안되었기 때문이다. 그런데 어제 다시 kbs 사이트에서 온에어를 실행해보니 팝업 차단을 하면 잘된다..ㅡㅡ;  뭐, 그래도 일단 시작한 것이니 계속 진행 해 봐야지...)


기능
기능은 별 거 없다. 일단 생각하고 있는 것은 이 정도...
1. kbs, mbc, sbs 라디오 채널 재생
2. 기타 채널 추가 기능
3. 녹음 기능
4. 예약 기능
5. 프로그램 정보 읽어 오기


개발 환경
이 참에 GNOME 어플리케이션 공부도 할 겸 개발 환경은 GNOME을 선택했다. 그리고 스트리밍 재생을 위한 프레임워크로는 GStreamer를, HTTP 클라이언트로는 libsoup를 사용하기로 했다. GUI는 일단 Gtk+로 만들고 나중에 GNOME 어플리케이션으로 변경해 보려 한다.

OS : Ubuntu 8.10 x86 / GNOME
Tool : vim / gcc / Anjuta
GUI : Gtk+ (추후 GNOME 어플리케이션으로 변경)
멀티미디어 프레임워크 : GStreamer
HTTP 클라이언트 : libsoup


개발 환경 구축
■ Gtk+ 개발 관련 패키지 설치
먼저 Gtk+로 개발할 때 필요한 파일들이 포함된 libgtk2.0-dev 패키지(및 의존성 걸리는 패키지들)를 설치한다. 설치 후 다음 명령을 실행했을 때 아래와 같이 인클루드 경로와 링크 플래그가 나와야 한다. 이 정보는 gcc로 gtk+ 프로그램을 컴파일할 때 사용된다.

young@y0un5:~$ pkg-config --cflags --libs gtk+-2.0
-I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12  -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lpangoft2-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lgio-2.0 -lcairo -lpango-1.0 -lfreetype -lz -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 
young@y0un5:~$

Gtk+ 컴파일도 해보고 예제 참고도 할 겸, gtk2.0-examples 패키지도 설치한다. 이 패키지를 설치하면
/usr/share/doc/gtk2.0-examples/examples/에 예제 소스가 Makefile과 함께 설치된다.
/usr/share/doc/gtk2.0-examples/examples/helloworld$에 helloworld.c 소스 파일이 있다. make를 실행하면 문제 없이 컴파일 되어야 한다(디렉토리 쓰기 권한이 root로 되어 있다는 것에 주의). Makefile을 열어 보면 pkg-config로 얻은 정보가 컴파일 시 사용되는 것을 볼 수 있다.

young@y0un5:/usr/share/doc/gtk2.0-examples/examples/helloworld$ cat Makefile

CC = gcc

CFLAGS = -Wall                 \
    -DG_DISABLE_DEPRECATED          \
    -DGDK_DISABLE_DEPRECATED     \
    -DGDK_PIXBUF_DISABLE_DEPRECATED \
    -DGTK_DISABLE_DEPRECATED

helloworld: helloworld.c
    $(CC) helloworld.c -o helloworld $(CFLAGS) `pkg-config gtk+-2.0 --cflags --libs`

clean:
    rm -f *.o helloworld
young@y0un5:/usr/share/doc/gtk2.0-examples/examples/helloworld$


vim 플러그인 gtk-vim-syntax도 설치하면 vim으로 작업하기 편하다. 당분간은 에디터로 vim을 쓸 것이기 때문에 이 플러그인도 설치하는 게 좋다. 설치 방법은 간단하다. 파일을 다운 받아 "~/.vim/after/syntax/"에 압축을 푼 후 c.vim.example 파일을 c.vim으로 변경하면 된다.


■ GStreamer 개발 패키지 설치
스트리밍 재생 기능을 구현하기 위해 GStreamer 개발 패키지를 설치한다. libgstreamer0.10-dev 패키지를 설치하고 이번에도 pkg-config를 실행하여 그 결과를 확인해 본다.
young@y0un5:~$ pkg-config --cflags --libs gstreamer-0.10
-pthread -I/usr/include/gstreamer-0.10 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/libxml2  -pthread -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lxml2 -lglib-2.0 
young@y0un5:~$

GStreamer 튜토리얼 사이트에 나온 helloworld 예제가 제대로 컴파일 되고 실행되는 지 확인해 본다.
young@y0un5:~$ gcc helloworld.c -o helloworld `pkg-config --cflags --libs gstreamer-0.10`


■ libsoup 개발 패키지 설치
사실 이 라이브러리는 온에어 방송을 듣는 데 필요 없지만 kbs는 사이트 로그인 후에만 스트리밍 재생이 되도록 되어 있기 때문에 HTTP 클라이언트 기능이 있어야 한다. HTTP 클라이언트 라이브러리로 libsoup를 택한 것은 별 다른 이유는 없고 GNOME Development Reference 사이트에 나와 있어서 그냥 쓰기로 했다. libsoup2.4-dev 패키지를 설치하고 역시 pkg-config를 실행하여 제대로 나오는 지 확인해 본다.

이제 IDE를 제외한 개발 환경은 모두 구축되었다. Anjuta IDE는 나중에 GUI를 만들 때 설치하기로 하고, 이제 Gtk+, GStreamer, libsoup를 공부해야 할 시간이다.


※ 참고 사이트






[Qt] 어플리케이션 다국어 지원

(소스 코드 내에 다국어를 지원하기 위한 처리 - tr(), QTranslator 등 - 가 되어 있다고 가정했을 때..)

1. 어플리케이션의 .pro 파일에 번역 파일(.ts)를 지정하는 부분 추가
예)
TRANSLATIONS = spreadsheet_de.ts \
                                 spreadsheet_fr.ts

2. lupdate 툴 사용하여 .ts 파일 생성
# lupdate -verbose spreadsheet.pro

3. Qt Linguist로 .ts 파일을 열어 각 언어에 맞게 번역

4. File | Release 메뉴 사용하여 .ts 파일을 .qm 파일로 변환
(모든 .ts 파일을 .qm 파일로 변환하고자 한다면 : # lrelease -verbose spreadsheet.pro)

※ .ts 파일(Translation Source) : XML 포맷, 번역시 사용.
     .qm 파일 (Qt message) : 어플리케이션에서 사용(QTranslator).


<참고 >
C++ GUI Programming with Qt3
http://doc.trolltech.com/3.3/linguist-manual.html

[Qt] 프로퍼티 사용하기

Qt에서 프로퍼티를 사용하기 위해서는 클래스 선언 내에 다음과 같은 형식으로 정의해주면 된다.
Q_PROPERTY( type name READ getFunction [WRITE setFunction]
[RESET resetFunction] [DESIGNABLE bool]
[SCRIPTABLE bool] [STORED bool] )


getFunction, setFunction은 이름 그대로이며 resetFunction은 디폴트 값으로 리셋하는 함수이다
(나머지는 http://doc.trolltech.com/3.3/properties.html 참조)

Q_PROPERTY 매크로로 등록된 프로퍼티는 Qt 디자이너의 프로퍼티 편집기에 나타난다.


■ 주의할 점
- Q_PROPERTY 매크로는 QObject의 서브 클래스에서만 사용 가능하다.
- Q_OBJECT 매크로 선언이 있어야 한다.
- setFunction은 const여야 한다.



■ 사용예
<선언>
...
class CustomButton : public QPushButton
{
Q_OBJECT
Q_PROPERTY(int num1 READ getNum1 WRITE setNum1)
...


<사용>
...
CustomButton button("Push Button", 0, "Quit");
button.setProperty("num1", 10);
int value = button.property("num1").toInt();
...

(C#에서처럼 num1 = 10, value = num1과 같이 쓸 수 없어서 불편하다.
또 프로퍼티 값을 얻어낼 때 QVariant 타입으로 나와서 다시 원래 타입으로 변환해줘야 한다.
-> 혹 다른 방법이 있을지도 모르니 더 알아보자...)

※ 참고 자료
http://doc.trolltech.com/3.3/index.html
C++ GUI Programming with Qt3 5장

[Qt] signal과 slot 사용하기

<< QT에서 signal과 slot기 사용시 주의할 점>>

■ signal과 slot은 QObject로부터 파생된 클래스의 멤버 함수이어야 한다.
■ 다중 상속을 사용하고 있다면, QObject는 클래스 목록의 가장 처음에 나와야 한다.
■ Q_OBJECT 구문이 클래스 선언에 나와야 한다.
■ signal은 템플릿에서 사용할 수 없다.
■ 함수 포인터는 signal과 slot에 대한 인자로 사용할 수 없다.
■ signal과 slot은 override될 수 없으며 public 상태로 업그레이드 될 수 없다.

.....Beginning Linux Programming 3rd 참조..


------------------------------------------------------------------------------------------------------------------------

qmake를 사용하면 moc(Meta Object Compiler)를 실행하는 부분을 Makefile에 추가하여 주므로 별도로 moc를 실행할 필요가 없다..그러나 signal과 slot이 정이된 헤더파일과 이름이 같은 cpp 파일이 필요..

[PHP] OCI8을 사용하여 오라클 DB 접근하기

OCI8을 사용하여 오라클 DB 접근하기

여기서는 PHP, httpd, OCI8을 연동하여 PHP에서 Oracle DB에 접근하는 방법을 설명한다.

PHP의 OCI8 함수는 Oracle Call Interface (OCI )를 사용하여 오라클 데이터베이스에 접근할 수 있도록 한다.

 

예제에 사용한 패키지 버전

PHP : 5.2.5

httpd : 2.2.8

Oracle Instant Client : 10.1.0.5

 

1) httpd를 컴파일하여 설치한다.

$ cd /zero/build/httpd-2.2.8

found_dbm=0 ./configure \

--prefix=/zero/env/httpd-2.2.8 \

--enable-so \

--enable-headers \

--enable-auth \

--enable-deflate \

--disable-negotiation \

--disable-include \

--disable-autoindex \

--disable-asis \

--enable-cgid \

--disable-alias \

--disable-actions

make; make install

 

 

2) Oracle 홈페이지에서 OS 환경에 맞는 Oracle Instant Client Package - Basic과 SDK를 다운 받아 설치하고자 하는 디렉토리에 압축을 푼다. 

(http://www.oracle.com/technology/tech/oci/instantclient/index.html)

$ cp instantclient-basic-linuxAMD64-10.1.0.5.0-20060519.zip  instantclient-sdk-linuxAMD64-10.1.0.5.0-20060519.zip  /zero/env/$ $ cd /zero/env/

$ unzip instantclient-basic-linuxAMD64-10.1.0.5.0-20060519.zip instantclient-sdk-linuxAMD64-10.1.0.5.0-20060519.zip

 

 

3) libclntsh.so.10.1 파일에 대한 심볼릭 링크를 생성해 준다(링크를 생성하지 않으면 PHP 컴파일 도중 에러가 발생한다.)

$ cd /zero/env/instantclient10_1

$ ln -s libclntsh.so.10.1 libclntsh.so

 

 

4) PHP를 컴파일하여 설치한다. 이 때 OCI8 관련 configure 옵션을 지정한다.

$ cd /zero/build/php-5.2.5

./configure --prefix=/zero/env/php-5.2.5 \

--with-apxs2=/zero/env/httpd/bin/apxs \

--with-iconv \

--with-oci8=instantclient,/zero/env/instantclient10_1 \

--enable-sockets \

--with-zlib \

--with-config-file-path=/zero/bin \

--enable-mbstring

make; make install

 

 

5) TNS_ADMIN 디렉토리를 생성한 후, 오라클 접속을 위한 tnsnames.ora 파일을 작성하여 저장한다.

$ mkdir /zero/TNS_ADMIN

$ vi /zero/TNS_ADMIN/tnsnames.ora

 

tnsnames.ora 파일 예)

ORA_SERVER=
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.254.0.5)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SID = ORA92)
    )
)

 

 

 

6) 오라클 환경변수를 다음과 같이 설정한 후, httpd를 실행한다.

export TNS_ADMIN=/zero/TNS_ADMIN   (tnsnames.ora 파일을 저장한 디렉토리)

export NLS_LANG=KOREAN_KOREA.UTF8         (접속하고자 하는 오라클 데이터베이스의 인코딩 설정에 따라)  

 

 

7) httpd의 Document 디렉토리에 다음과 같은 PHP 테스트 페이지를 작성한 후, 브라우저에서 접속해 본다.

<?

phpinfo();

?>

 

OCI8 설정이 enabled되어 있는지 확인한다. 만약 아래와 같은 항목이 없다면 제대로 설치가 되지 않은 것이므로 위 설치 과정을 다시 점검한다.

 

php_oci2.jpg

 

 

8) 다음과 같은 코드를 작성하여 오라클 접속 및 쿼리 테스트를 한다. 이 때 한글이 깨진다면 NLS_LANG 환경변수 설정이 맞는지 확인해 본다.

 

<?
  $conn 
oci_connect('user''pass''ORA_SERVER'); // 인자는 오라클 아이디, 비밀번호, tnsnames.ora에 정의된 오라클 인스턴스 이름
  if (!
$conn) {$e oci_error();

    print htmlentities($e['message']);
    exit;
  }
$query 'SELECT * FROM DEPARTMENTS';$stid oci_parse($conn$query);
  if (!
$stid) {$e oci_error($conn);
    print 
htmlentities($e['message']);
    exit;
  }
$r oci_execute($stidOCI_DEFAULT);
  if (!
$r) {$e oci_error($stid);
    echo 
htmlentities($e['message']);
    exit;
  }


  print '<table border="1">';
  while (
$row oci_fetch_array($stidOCI_RETURN_NULLS)) {
    print 
'<tr>';
       foreach (
$row as $item) {
         print 
'<td>'.($item?htmlentities($item):'&nbsp;').'</td>';
       }
       print 
'</tr>';
  }
  print 
'</table>';oci_close($conn);

?>

 

 

참고 사이트

http://www.oracle.com/technology/global/kr/pub/notes/technote_php_instant.html

http://www.php.net/manual/en/book.oci8.php

 

 

 

 

 

 

 

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

prev 1 next