Caution on Using Qt Speech on Android: single instance

When using Qt Speech on Android, you need to have only one single QTextToSpeech object to have proper locale setup. Otherwise setLanguage() call via JNI fails.

What a day(lol).

안드로이드에서 Qt Speech 사용시 유의점: 단일 인스턴스


QTextToSpeech를 단일 instance로 생성해서 공유 사용해야 로케일 설정이 제대로 됩니다. 이렇게 하지 않으면 JNI를 통해 setLanguage()를 호출할때 locale 설정이 안되는 문제가 생기더군요.



역시 삽질도 하기 나름입니다.

First impressions on Android programming

During the holidays I could have a chance to dig into Android programming and got some short thought. I share them here, hoping that these would help someone else.
  • The programming environment of Android is literally fantastic. Now I can understand why a lot of companies are seriously considering Android in their embedded environment.
  • Java is...... too slow(OTL). Damn slow. I can't wait for the delay
  • I could, eventually, build Qt for Android in Windows
    • Build environment: Qt 5.9.2 + SDK Level 19 + NDK r15c + BuildTools 26.0.2 + JDK 8 + Windows 10 64bit (find_java.bat in Android SDK can't find JDK 9. -_-)
    • Qt Creator 4.4.0 can't recognize SDK Buildtools 26.X. At least 4.4.1 is needed
    • QTextToSpeech seems to fix the locale to system in Android, and can't be changed(In Java you can). However, considering that I accidentally hear TTS in other locale in the app, we may have some change(or it may be simply and error)

안드로이드 프로그래밍 경험기

그간 연휴도 있고 해서 안드로이드 프로그래밍을 좀 각잡고 파고들었습니다. 몇가지 단상들이 남아서 혹시 도움이 될까 하여 정리해봅니다.
  • Android의 프로그래밍 환경은 정말 기립박수를 치고 싶을 정도로 훌륭함. 왜 많은 회사들이 Android를 임베디드 환경에서 매우 긍정적으로 검토하는지 이해가 됨
  • Java는...... 매우 느림(OTL). 답답함. 못써먹겠음
  • 수많은 삽질 끝에 Windows에서 Qt for Android 빌드 성공
    • Qt 5.9.2 + SDK Level 19 + NDK r15c + BuildTools 26.0.2 + JDK 8 + Windows 10 64bit 기반(JDK 9은 Android SDK의 find_java.bat가 인식을 못하더군요. -_-)
    • Qt Creator 4.4.0은 SDK Buildtools 26.X대를 정상적으로 인식하지 못함. 최소 4.4.1이 필요
  • QTextToSpeech는 locale이 시스템 로케일로 고정되며, 변경할 수 없는 것으로 생각됨(Java에선 가능한디......). 하지만 테스트 앱에서 시스템 로케일을 변경하지 않은 상태에서 다른 로케일의 TTS 출력이 가능했던걸 보면, 어쩌면 방법이 있을지도 모름(아니면 단순 오동작이었을지도......).

Developing SNMP trap handlers using Net-SNMP

Net-SNMP is used as standard SNMP manager by almost all Linux distribution, which is de facto standard. I had a chance to develop a handler application for SNMP Trap message, and I'd like to write down some of the important stuff.

[Configuration, test, and troubleshooting]
  • snmptrapd can send received SNMP trap to stdout with designated format
  • Running snmptrapd in foreground and showing logs in stdout
    • snmptrapd -f -Lo -c snmptrapd.conf
  • If snmptrapd can't receive traps, iptables may block it
    • iptables -I INPUT -p udp -m udp --dport 162 -j ACCEPT
    • iptables-save > /etc/sysconfig/iptables
  • In CentOS, if snmptrapd can't read /etc/snmp/snmptrapd.conf, SELinux  security label may be incorrect
    • ls -Z /etc/snmp/snmptrapd.conf (compare labels with other files, e.g. snmpd.conf with ls -Z command)
    • chcon system_u:object_r:etc_t:s0 /etc/snmptrapd.conf
[/etc/snmp/snmptrapd.conf example]
disableAuthorization yes
authCommunity log,execute,net public
#logoption -Lf /root/snmp.log
#logOption -Lo

#format execute %B\n%b\n%V\n%v\n <- default
format execute %b\n%V\n%v\n
#man snmptrapd:FORMAT SPECIFICATIONS for format details
# %b: [Protocol(UDP/TCP] source IP:port -> destination IP:port
# %V: separators between trap values
# %v: actual values representation

#format print1
#format print2

traphandle default /Automata/AutomataSnmpTrapReader
# default: handle everything

Net-SNMP 기반의 SNMP Trap 연동 프로그램 개발

Net-SNMP는 거의 모든 리눅스 배포본에서 표준 SNMP 관리자로 사용되고 있는, 사실상의 표준이라고 할 수 있는 범용적인 도구입니다. 이번에 기회가 있어서 SNMP Trap 메시지를 받아서 처리는 도구를 만들게 되었는데, 개발중 중요하다고 생각되는 내용 몇 가지를 옮겨 적고자 합니다.

[설정 및 테스트]
  • snmptrapd는 받은 SNMP trap을 지정된 형식을 사용하여 stdout으로 보낼 수 있음
  • snmptrapd를 foreground에서 실행하면서 stdout으로 로그 보내기
    • snmptrapd -f -Lo -c snmptrapd.conf
  • snmptrapd가 보낸 trap을 못 받는 경우 iptables가 막는 경우일 수 있음
    • iptables -I INPUT -p udp -m udp --dport 162 -j ACCEPT
    • iptables-save > /etc/sysconfig/iptables
  • CentOS에서 snmptrapd가 /etc/snmp/snmptrapd.conf를 읽지 못하는 경우 SELinux  보안 레이블이 잘못되어서일 수 있음
    • ls -Z /etc/snmp/snmptrapd.conf (ls -Z를 통해 snmpd.conf 등 파일과 레이블 비교)
    • chcon system_u:object_r:etc_t:s0 /etc/snmptrapd.conf
    [/etc/snmp/snmptrapd.conf 예시]
    disableAuthorization yes
    authCommunity log,execute,net public
    #logoption -Lf /root/snmp.log
    #logOption -Lo

    #format execute %B\n%b\n%V\n%v\n <- default
    format execute %b\n%V\n%v\n
    #man snmptrapd:FORMAT SPECIFICATIONS for format details
    # %b: [Protocol(UDP/TCP] source IP:port -> destination IP:port
    # %V: separators between trap values
    # %v: actual values representation

    #format print1
    #format print2

    traphandle default /Automata/AutomataSnmpTrapReader
    # default: handle everything

    wxWidgets: memory of a month(+list of complaints)

    Recently, with some motivation, I left Qt and used wxWidgets for a while. I used Code::Blocks, applied Bind<>(), and so on. I enjoyed the coding, but eventually I returned to Qt. During the time, I experienced......:

    • If the application is frozen, task switcher doesn't work at all, whatever it is - Alt-Tab, Windows-Tab, taskbar click..... Nothing works. This is first time I've ever seen something like this
    •  You need some time to be accustomed to properly use wxDateTime. On calculation you use wxDateSpan, and its structure is confusing
    • In wxGrid, if you have too many rows ans set the layout side to 1 or higher, the grid wraps the entire window(......). The widget seems to calculate its size based on the sum of column widths and row heights. It must be a bug
    • Unicode adoption seems not working properly. I converted interface strings to UTF-8 using wxConvUtf8 and tried to put the string via SOCI, and Firebird complained whenever the string has some Chinese characters
    • It seems to be due to Windows control itself, but it's too slow. The fame of GDI is not void.

    And above all, Code::Blocks broke down from time to time, and well, just guess what it would feel like if you experience all above.
    For your reference, my development environment was as follows:

    • wxWidgets 3.1
    • MinGW-w64 6.3.0 release 1
    • Code::Blocks rev10922(built at Nov. 20th. 2016)

    Now I'm back to Qt, and I'm porting all my wxWidgets apps to Qt now. The apps are faster, and it's more convenient. Viola!

    wxWidgets: 한 달간의 추억(+투덜투덜 목록)

    근저 약간의 계기로 Qt를 버리고 한동안 wxWidgets를 사용했더랬습니다. Code::Blocks를 사용하고, Bind<>()도 좀 쓰고, 뭐 기타등등 그랬습니다. 한동안 꽤 즐겁게 코딩을 했는데, 결국에는 Qt로 돌아오게 되더군요. 그러니까 그동안 무슨 일을 겪었는가 하니......
    • 프로그램이 freezing 상태가 되면 task switcher가 동작하지 않습니다. Alt-Tab이고 Windows-Tab이고 작업표시줄 클릭이고 뭐고간에 하나도 동작하지 않아요. 시스템이 통째로 얼어버리는건 처음 봤습니다
    • wxDateTime은 익숙해지는데 시간이 꽤 오래 걸립니다. 연산에 wxDateSpan이라는 별도의 클래스를 사용하는데, 이게 구조가 좀 그렇더군요.
    • wxGrid의 열의 갯수가 너무 많은 상태에서 layout 크기를 1보다 크게 잡으면 grid가 창 전체를 뒤덮어버립니다(......). 아무래도 widget의 크기를 widget의 기본 크기가 아니라 내부 행/열의 크기의 합계로 계산하는 것 같습니다. 아무리 봐도 버그인데요. -_-
    • 유니코드 제어가 완전하지 않은 것 같습니다. wxConvUtf8으로 인터페이스의 글자를 UTF-8으로 변환한 뒤 SOCI를 통해 UTF-8 DB에 넣으려고 해봤는데, 글자에 한문만 들어가면 Firebird가 잘못된 글자라면서 오류를 뱉어내더군요
    • 이건 Windows 컨트롤의 한계인 것 같은데, 컨트롤이 꽤 느립니다. GDI의 명성은 헛된 것이 아니었어요. -_-
    여기에 Code::Blocks의 툭하면 죽는 현상까지 가세하니 대략 난감하더군요(-_-).
    참고로 개발환경은 아래와 같습니다.
    • wxWidgets 3.1
    • MinGW-w64 6.3.0 release 1
    • Code::Blocks rev10922(2016년 11월 20일 빌드)
    참고로 지금은 Qt로 돌아왔고, wxWidgets로 만들었던 프로그램도 모두 Qt로 porting하고 있습니다. 속도도 빨라지고 위에 이야기했던 불편함도 없고...... 훨씬 쾌적하네요. Viola!

    QSqlQuery vs. SOCI: inserting 1000 times

    Recently I'm using QtWebApp to develop an application, and I did some performance benchmark to select a database library in the backend.  I selected QSqlQuery and SOCI as candidates, and tried to insert 10,000 rows at once. The result is as follows:

    • Repeating single query
      • QSqlQuery: 10000ms
      • SOCI: 2500ms
    • Prepared statement
      •  QSqlQuery: 7000ms
      • SOCI: 750ms(?!)
    In any situation, SOCI takes far less time than QSqlQuery. QSqlQuery seems to be really a bad choice for server applications. I suspect the bottleneck is the loooooong processing time for QString.

    QSqlQuery vs. SOCI: 1000회 연속 insert

    최근 QtWebApp을 기반으로 프로그램을 개발하고 있는 바, backend에서 사용할 DB 라이브러리를 써보려고 성능 테스트 비슷한걸 해봤습니다. 후보로는 QSqlQuery와 SOCI를 선택했고, 연속으로 10,000회 insert를 시도했습니다. 결과는 아래와 같습니다:
    • 단일 쿼리 반복
      • QSqlQuery: 10000ms
      • SOCI: 2500ms
    • Prepared statement
      • QSqlQuery: 7000ms
      • SOCI: 750ms(?!)
    어떤 상황에서든, SOCI가 QSqlQuery를 훨씬 뛰어넘는 처리속력을  보여주고 있습니다. 아무래도 QSqlQuery는 서버 상황에서는 썩 좋은 선택은 아닌 것 같습니다. 아무래도 쿼리를 구성하는데 사용되는 QString 특유의 비대함(?)이 문제가 아닐까 하는 생각이 드네요.

    블로그를 이전합니다

    뭐, 이런 작은 변방의 블로그에 관심있으신 분들은 아무도 없으시리라 생각합니다만...... (웃음) 블로그 플랫폼을 블로거에서 dev.to로 옮겼습니다. 새 URL은 아래와 같습니다: https://dev.to/teminian 새로운 거처에서 뵙겠습니...

    Popular in Code{nested}