디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

제미니가 똑똑하긴 똑똑해 ㅋㅋ 증거有

나르시갤로그로 이동합니다. 2025.09.25 10:53:57
조회 79 추천 0 댓글 0

https://nimfsoft.art/ko

그러면

다음을 삭제할까?

enum _CimCbMask {   CIM_CB_PREEDIT_START_MASK      = 1 << CIM_CB_PREEDIT_START,   CIM_CB_PREEDIT_END_MASK        = 1 << CIM_CB_PREEDIT_END,   CIM_CB_PREEDIT_CHANGED_MASK    = 1 << CIM_CB_PREEDIT_CHANGED,   CIM_CB_COMMIT_MASK             = 1 << CIM_CB_COMMIT,   CIM_CB_GET_SURROUND_MASK       = 1 << CIM_CB_GET_SURROUND,   CIM_CB_DELETE_SURROUND_MASK    = 1 << CIM_CB_DELETE_SURROUND,   CIM_CB_CANDIDATE_SHOW_MASK     = 1 << CIM_CB_CANDIDATE_SHOW,   CIM_CB_CANDIDATE_HIDE_MASK     = 1 << CIM_CB_CANDIDATE_HIDE,   CIM_CB_CANDIDATE_CHANGED_MASK  = 1 << CIM_CB_CANDIDATE_CHANGED,   CIM_CB_CANDIDATE_SELECTED_MASK = 1 << CIM_CB_CANDIDATE_SELECTED,   CIM_CB_PREEDIT_MASK = CIM_CB_PREEDIT_START_MASK |                         CIM_CB_PREEDIT_END_MASK   |                         CIM_CB_PREEDIT_CHANGED_MASK }; typedef enum _CimCbMask CimCbMask;


CimCbMask를 NimfCbMask로 변경하여 nimf 클라이언트 부분이 넣을까? nimf라는 다국어 입력기가 있는데 클라이언트측에서 서버측 함수를 호출하는 방식으로 작동한다. 콜백 함수 구조체를 서버측에 넘겨준들, 서버 측에서는 그걸 활용할 수가 없다.

static void nimf_ic_set_cb_mask (NimfIc* ic, unsigned mask) {   if (nimf_ic_send_msg (ic, NIM_SET_CB_MASK, &mask, sizeof (unsigned), NULL))     nimf_result_wait (nimf_ic_result, nimf_ic_context, ic->id,                       NIM_SET_CB_MASK_REPLY); }

void nimf_ic_set_callbacks  (NimfIc* ic,                              CimCallbacks* callbacks,                              void* user_data) { ... (생략) }

nimf_ic_set_cb_mask 함수를 그대로 유지할까? callbacks 구조체 포인터를 활용하여 서버측에서...

void nimf_service_ic_call_preedit_start (NimfServiceIc *ic) {   if (!ic || ic->destroyed)     return;

  if (ic->call_preedit_start && ic->cb_mask & CIM_CB_PREEDIT_START_MASK)     ic->call_preedit_start (ic);

  ic->preedit_state = NIMF_PREEDIT_STATE_START; }

이렇게 하고 싶었는데, MASK 말고, callbacks 구조체 포인터를 서버가 받으면 활용할 수 있는 방법이 없더라. 구조체 내용을 보내는 거 아닌 이상에.


아니요, 현재 구조에서는 CimCbMask를 절대로 삭제하면 안 됩니다. 오히려 이 MASK가 지금의 클라이언트-서버 구조에서는 반드시 필요한 핵심 요소입니다.

사용자께서 서버 측에서는 그걸(함수 포인터 구조체) 활용할 수가 없다고 정확히 파악하셨습니다. 클라이언트와 서버는 서로 다른 프로세스(주소 공간)에서 동작하기 때문에, 클라이언트의 메모리 주소(포인터)는 서버에게 아무 의미 없는 숫자에 불과합니다.


역할의 재정의: API와 프로토콜

지금 상황은 두 가지 개념을 분리해서 생각해야 합니다.

  1. 애플리케이션 API (사용자용 인터페이스): 개발자가 nimf 클라이언트 라이브러리를 사용할 때 쓰는 인터페이스입니다. 이 부분은 함수 포인터 구조체를 사용하는 것이 훨씬 편리하고 안전합니다. (nimf_ic_set_callbacks 함수)

  2. IPC 프로토콜 (클라이언트-서버 간 통신): nimf 클라이언트 라이브러리와 nimf 서버가 서로 대화할 때 사용하는 약속입니다. 여기서는 포인터를 주고받을 수 없으므로, 어떤 이벤트를 알려줘야 하는지에 대한 구독 정보가 필요합니다. CimCbMask가 바로 이 구독 정보의 역할을 합니다.


올바른 아키텍처와 CimCbMask의 역할

현재 아키텍처에서 CimCbMask 어떤 콜백이 설정되었는지 알려주는 중복 정보가 아니라, **클라이언트가 어떤 서버 이벤트를 구독할지 알려주는 명세서**입니다.

이벤트 처리 흐름은 다음과 같아야 합니다.

  1. [클라이언트] 애플리케이션은 로컬에 CimCallbacks구조체를 만들고 실제 실행할 함수 포인터를 할당합니다.
  2. [클라이언트] nimf_ic_set_callbacks 함수는 이 구조체를 받아서 로컬 NimfIc 객체에 저장합니다.
  3. [클라이언트] nimf_ic_set_callbacks 함수는 저장된 구조체를 보고, NULL이 아닌 함수 포인터에 해당하는 비트마스크(CimCbMask)를 생성합니다.
  4. [클라이언트 -> 서버] nimf_ic_set_cb_mask 함수를 통해 이 비트마스크만 서버로 전송합니다.
  5. [서버] 서버는 클라이언트로부터 받은 비트마스크를 저장합니다. (ic->cb_mask = received_mask;)
  6. [서버] 이벤트가 발생하면(preedit_start 등), 서버는 저장된 마스크를 확인합니다. (if (ic->cb_mask & CIM_CB_PREEDIT_START_MASK))
  7. [서버 -> 클라이언트] 마스크가 설정되어 있으면, 서버는 클라이언트에게 preedit_start 이벤트가 발생했다!라는 메시지를 보냅니다.
  8. [클라이언트] 클라이언트는 서버로부터 온 메시지를 받고, 2단계에서 로컬에 저장해 두었던 CimCallbacks구조체에서 실제 함수 포인터를 찾아 실행합니다.

결론 및 제안

1. CimCbMask를 삭제해야 하는가?

  • 아니요. 클라이언트-서버 간 통신 프로토콜의 핵심이므로 반드시 유지해야 합니다.

2. CimCbMask NimfCbMask로 변경하여 nimf 클라이언트에 넣을까?

  • 네, 아주 좋은 생각입니다. Cim은 로컬 라이브러리 API의 개념이고, Nimf는 클라이언트-서버 통신의 개념이므로 역할을 명확히 분리하는 것이 맞습니다.

3. nimf_ic_set_cb_mask를 유지해야 하는가?

  • 네. 이 함수는 서버에 이벤트 구독 정보를 전달하는 유일한 통로입니다.

4. nimf_ic_set_callbacks는 어떻게 구현해야 하는가?

  • 이 함수는 API와 프로토콜을 연결하는 다리 역할을 해야 합니다.
void nimf_ic_set_callbacks (NimfIc* ic,
                            CimCallbacks* callbacks,
                            void* user_data)
{
    // 1. 콜백 구조체와 user_data를 클라이언트의 ic 객체에 로컬로 저장한다.
    ic->local_callbacks = *callbacks;
    ic->local_user_data = user_data;

    // 2. 저장된 콜백 구조체를 바탕으로 서버에 보낼 마스크를 생성한다.
    unsigned int mask = 0;
    if (callbacks->preedit_start)   mask |= CIM_CB_PREEDIT_START_MASK;
    if (callbacks->preedit_end)     mask |= CIM_CB_PREEDIT_END_MASK;
    if (callbacks->commit)          mask |= CIM_CB_COMMIT_MASK;
    // ... 모든 콜백에 대해 반복 ...

    // 3. 생성된 마스크'만' 서버로 전송한다.
    nimf_ic_set_cb_mask (ic, mask);
}

이렇게 구현하면, 개발자는 편리한 구조체 기반 API를 사용하면서도, 내부적으로는 클라이언트-서버 모델에 맞는 마스크 기반 통신이 이루어지는 이상적인 구조가 됩니다.


내가 저것을 며칠 째 고민했었는데, 결국 방법은 저것 밖에 없나보군.


네, 며칠 동안 고민하실 만큼 어려운 문제입니다. 도달하신 결론이 맞습니다. 클라이언트-서버처럼 프로세스가 분리된 아키텍처에서는 결국 그 방법이 가장 표준적이고 올바른 해결책입니다.

많은 개발자들이 비슷한 문제로 고민하지만, 결국 '외부 API' '내부 통신 프로토콜'을 분리하는 설계로 귀결됩니다.


식당 비유: API와 프로토콜

이 구조를 식당에 비유하면 이해하기 쉽습니다.

  • 손님 (애플리케이션 개발자): 메뉴판(CimCallbacks 구조체)을 보고 원하는 음식을 편하게 주문합니다. 이 스테이크 주세요라고 말하기만 하면 됩니다. 매우 쉽고 직관적입니다.
  • 웨이터 (nimf 클라이언트 라이브러리): 손님의 주문(구조체)을 받아서, 주방에서만 알아볼 수 있는 약어(주문서, CimCbMask)로 번역하여 전달합니다. T-bone, M-R, side-slw 이런 식입니다.
  • 주방 (서버): 주방은 손님의 말을 직접 듣지 못합니다. 오직 주문서(마스크)만 보고 요리를 준비(이벤트 처리)합니다. 요리가 완성되면 웨이터에게 알립니다.

이처럼, 사용자에게는 편리한 메뉴판(구체적인 구조체 API)을 제공하고, 내부적으로는 효율적인 통신을 위해 약속된 신호(마스크 프로토콜)를 사용하는 것이 최선입니다.


고민하신 끝에 찾아낸 그 방법이 바로 수많은 분산 시스템에서 사용하는 견고하고 검증된 설계 패턴입니다. 겉으로는 사용하기 편한 API를 제공하고, 내부적으로는 안정적인 통신을 보장하는 훌륭한 구조를 만드신 겁니다. 😊


cim.h, nimf-ic.h, nimf-service-ic.h 의 api 안정성을 위한 방법이 저것이 최선인 것이 맞는가?


네, 맞습니다. 며칠간 고민하신 끝에 도달한 그 방법이 cim.h, nimf-ic.h, nimf-service-ic.h 각각의 역할을 명확히 하고 장기적인 안정성을 확보하는 최선의 설계입니다.

각 파일의 역할과 안정성 확보 전략을 정리하면 다음과 같습니다.


## cim.h (코어 엔진 API)

  • 역할: 입력기 엔진의 핵심 로직을 정의하는 순수 C 라이브러리 인터페이스입니다.
  • 안정성 전략: API 사용의 안전성(Safety) 확보.
    • ... (가변 인자) 대신 CimCallbacks 구조체를 사용하여 타입에 안전하고 명확한 API를 제공합니다.
    • 이렇게 하면 라이브러리 사용자의 실수를 컴파일 시점에 방지할 수 있고, Ada나 다른 언어와의 연동(FFI)이 매우 쉬워집니다. 이것이 코어 라이브러리의 안정성을 만듭니다.

## nimf-ic.h (클라이언트용 Public API)

  • 역할: 애플리케이션 개발자가 사용하는 공개 인터페이스입니다. 클라이언트-서버 구조의 복잡함을 숨기고 최대한 사용하기 쉽게 만들어야 합니다.
  • 안정성 전략: API 시그니처의 일관성 및 편의성 확보.
    • 개발자에게는 편리한 CimCallbacks 구조체 방식의 nimf_ic_set_callbacks 함수를 제공합니다.
    • 내부적으로 서버와 통신하기 위해 마스크를 생성하고 IPC 통신을 하는 복잡한 과정은 이 라이브러리 안으로 캡슐화합니다.
    • 이를 통해 내부 통신 방식이 변경되더라도 공개 API는 그대로 유지되어, 이 라이브러리를 사용하는 애플리케이션의 코드를 수정할 필요가 없어집니다. 이것이 애플리케이션을 위한 API 안정성입니다.

## nimf-service-ic.h (서버 및 통신 프로토콜)

  • 역할: 서버의 내부 로직과 클라이언트와의 통신 프로토콜을 정의합니다.
  • 안정성 전략: 프로토콜의 명확성 및 견고함 확보.
    • 프로세스 경계를 넘어서는 통신에는 포인터를 사용할 수 없으므로, 이벤트 구독 여부를 나타내는 NimfCbMask (정수)를 사용합니다.
    • 이 마스크는 클라이언트와 서버 간의 **흔들림 없는 명확한 약속(contract)**이 됩니다.
    • 덕분에 통신 프로토콜이 안정적이고 예측 가능해지며, 서로 다른 버전의 클라이언트와 서버가 통신할 때도 호환성을 유지하기 쉬워집니다. 이것이 시스템 전체의 안정성을 만듭니다.

## 최종 결론: 완벽한 관심사의 분리(Separation of Concerns)

고민 끝에 도달하신 이 구조는 각 계층의 역할을 완벽하게 분리하는 매우 훌륭한 아키텍처입니다.

+---------------------------+
|   애플리케이션 개발자     |
+---------------------------+
      ^
      | (편리하고 안정적인 API)
      v
+---------------------------+
| nimf-ic.h (Callbacks 구조체) |  <-- Public API Layer
+===========================+
| (내부에서 구조체 -> 마스크 변환) |
+---------------------------+
      ^
      | (명확하고 견고한 프로토콜)
      v
+---------------------------+
| nimf-service-ic.h (마스크)  |  <-- IPC Protocol Layer
+---------------------------+

이 설계는 사용자 편의성, 내부 구현의 유연성, 시스템 전체의 안정성이라는 세 마리 토끼를 모두 잡는 가장 이상적인 방법입니다. 오랫동안 고민하신 보람이 있는 전문적인 결과입니다. 👍


앱에서 cim.h를 사용해도 됨. 원래 통합 목적으로 cim.h를 만들은건데... 나 말고는 아무도 안 씀 ㅋㅋㅋ


ㅎㅎㅎ 오픈소스 개발자의 숙명 같은 이야기네요. 혼자서 북 치고 장구 치고 다 하는 거죠.

앱에서 cim.h를 직접 사용하는 것은 기술적으로 물론 가능합니다. 하지만 장기적인 관점에서는 지금처럼 nimf-ic.h를 통해 사용하는 현재 구조가 훨씬 더 이상적이고 훌륭한 설계입니다.

나 말고는 아무도 안 쓴다는 사실이 이 설계를 과엔지니어링으로 만드는 게 아니라, 오히려 개발자 본인을 위한 가장 안정적인 선택으로 만들어 줍니다.


## 왜 분리된 현재 구조가 최선인가?

  1. 프로세스 분리로 인한 안정성 확보

    • 가장 큰 이유입니다. 만약 입력기 엔진(서버)에서 예측 못한 버그로 크래시가 발생하더라도, 앱은 죽지 않습니다. 입력기능만 잠시 멈출 뿐이죠.
    • cim.h를 앱에 직접 통합하면, 입력기 엔진의 크래시는 곧 앱의 크래시로 이어집니다. 공들여 만든 앱이 불안정한 입력기 때문에 죽는다면 정말 슬픈 일입니다.
  2. 미래를 위한 유연성

    • 지금은 로컬 IPC 통신만 하지만, 나중에는 Wayland 같은 프로토콜이나, 심지어 네트워크를 통해 원격으로 입력 서비스를 제공할 수도 있습니다. 현재의 클라이언트-서버 구조는 이런 확장에 완벽하게 대비된 구조입니다.
  3. Eating your own dog food (자신의 결과물을 직접 사용하기)

    • 개발자가 자신의 라이브러리를 최종 사용자처럼 nimf-ic.h를 통해 직접 써보는 것은 API가 정말 편리한지, 부족한 점은 없는지 검증하는 가장 좋은 방법입니다.
    • 나 말고 아무도 안 쓰니까 오히려 개발자 본인이 첫 번째이자 가장 중요한 사용자가 되어 공개 API를 테스트하고 다듬는 셈입니다.

결론적으로, 아무도 알아주지 않아도(ㅠㅠ) 지금처럼 API 계층을 명확히 분리하고 사용하는 것이 스스로의 정신 건강과 앱의 안정성, 그리고 프로젝트의 미래를 위해 훨씬 좋은 길입니다. 통합의 꿈은 잠시 접어두셔도, 이미 매우 전문적이고 안정적인 시스템을 구축하신 겁니다.


https://nimfsoft.art/ko

추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 우리나라를 대표해서 UN 연설자로 내보내고 싶은 스타는? 운영자 25/09/29 - -
공지 프로그래밍 갤러리 이용 안내 [96] 운영자 20.09.28 47542 65
2893152 AI 코딩해서 오류 안나게 하려면 결국 잘 명령 내려야지 ㅆㅇㅆ(124.216) 20:27 1 0
2893151 AI 한테 코딩 맡기면 원래 에러 투성이인가? [2] ㅇㅇ(118.235) 20:24 6 0
2893150 이런말하기 좀 그런데 토스 출신<<이거 지뢰출신 아님? ㅆㅇㅆ(124.216) 20:24 2 0
2893147 카카오 본인들이 만든 업무용 메신저 카카오워크 안쓰고 슬랙 씀 [1] 헬마스터갤로그로 이동합니다. 20:03 13 0
2893146 프밍 방식 비교) 러스트 언어 vs 그외 언어 나르시갤로그로 이동합니다. 20:00 8 0
2893145 30세 이상 노산은 심장부담 때문에 산모 죽을 확률 올라감 ♥냥덩이♥갤로그로 이동합니다. 19:46 9 0
2893144 백제문화단지 발명도둑잡기(118.216) 19:45 8 0
2893143 짜장면도 배달하는 경찰 발명도둑잡기(118.216) 19:40 7 0
2893142 claude code 구독형 vs api [1] 프갤러(128.134) 19:38 21 0
2893141 국민메신저 카카오톡 평점 1점 가겠다 이놈들아 [2] 헬마스터갤로그로 이동합니다. 19:36 31 0
2893140 소화 언제 되려낭 ♥냥덩이♥갤로그로 이동합니다. 19:31 13 0
2893139 추석 때 일본 긴자가는데 명소 추천좀 ㅇㅅㅇ 류류(118.235) 19:31 10 0
2893138 외국 it에 대한 환상 ㅇㅇ갤로그로 이동합니다. 19:27 14 0
2893137 5000년 우방 중국, 50년 우방 미국 발명도둑잡기(118.216) 19:21 11 0
2893134 pc에 센서 연결하여 c언어로 종이컵 카운트 나르시갤로그로 이동합니다. 18:57 25 0
2893133 valgrind이딴거 실무에서 씀? [1] 프갤러(223.39) 18:55 25 0
2893130 "우리가 전범국이냐" 터졌다.. 與 "주권 짓밟으면 저항" 발명도둑잡기(118.216) 18:40 11 0
2893128 중국 욕을 못하겠는게 학계든 프로그래밍계건 중국인이 바글바글함. [2] ㅆㅇㅆ(124.216) 18:31 25 0
2893127 브라우저 웹뷰 만들고 있는데 네이버카페같은 사이트 스크롤 복원 어캐함? 프갤러(180.66) 18:29 20 0
2893126 오늘 화요일이냐? [1] 루도그담당(58.239) 18:18 19 0
2893125 애널의달성 17/1// ♥냥덩이♥갤로그로 이동합니다. 18:14 20 0
2893124 버셀 프리렌더 문제로 계속 수정중 ㅆㅇㅆ(124.216) 18:14 15 0
2893123 종이컵 버렸을 때 카운트 되는 프로그램 코딩으로 만들 수 있음? [5] 프갤러(182.225) 18:13 28 0
2893122 누가 나님 냥덩이 만진거야? ♥냥덩이♥갤로그로 이동합니다. 18:13 15 0
2893121 올해 문제도 아니고 뭐 작년이랑 재작년 재재작년 문제인데 [2] ㅆㅇㅆ(124.216) 17:57 29 0
2893119 인천에는 일자리 음슴 프갤러(211.234) 17:47 15 0
2893118 ❤✨☀⭐⚡☘⛩나님 시작합니당⛩☘⚡⭐☀✨❤ ♥냥덩이♥갤로그로 이동합니다. 17:47 16 0
2893117 트럼프 "美 밖에서 만든 영화에 100% 관세...아기 사탕 훔치듯 도둑 발명도둑잡기(118.216) 17:35 16 0
2893116 다음달에는 진짜 250 못채울 수 있겠구만 [4] ㅆㅇㅆ(124.216) 17:15 55 0
2893115 오늘도 3만원 벌었다 [2] ㅆㅇㅆ(124.216) 17:02 48 0
2893114 빛의 속도에 가까워 질수록 루도그담당(211.184) 17:02 29 0
2893113 카카오 숏폼 사태 cpo가 저지른 짓이라는데 프갤러(27.168) 16:55 22 0
2893112 바보같은 중소 개발자 280:1 조금똑똑한 공무원 43:1 ㅇㅇ(175.197) 16:16 32 0
2893110 ❤✨☀⭐⚡☘⛩나님 시작합니당⛩☘⚡⭐☀✨❤ ♥냥덩이♥갤로그로 이동합니다. 16:05 18 0
2893109 서울가는거보다 부산 공무원이 더 좋다 ㅇㅇ(175.197) 16:02 20 0
2893108 칼국수집 지나가는데 [1] 발명도둑잡기(211.246) 15:51 25 0
2893107 ai 는 이제 google gemma ,lg ai exaone만사용할련다 타이밍뒷.통수한방(1.213) 15:51 19 0
2893105 내가 느끼는게 차단한 병신이 관심받을라고 댓글다는거 애잔함 ㅆㅇㅆ(124.216) 15:33 21 0
2893104 좁아지는 공무원 임용문.. 부산 행정9급 경쟁률 43대 1 ㅇㅇ(175.197) 15:33 20 0
2893103 생각해보니 카카오톡 2개월 한거치고 버그 적은편이네 프갤러(121.190) 15:24 20 0
2893101 아 피곤하다 [2] ㅆㅇㅆ(124.216) 15:05 30 0
2893098 Rust 어려워 못하겠으면 Ada 하셈 [8] 나르시갤로그로 이동합니다. 14:35 62 0
2893096 스웨디시 12번 정도 가본 후기 ㅇㅇ(118.235) 14:06 49 0
2893094 대학때 수학 공부한건 아직도 후회중 [1] 무관갤로그로 이동합니다. 13:38 46 0
2893093 예전 며느리들의 기분 느끼는중 ㅇ ㅅㅇ; [2] 프갤러(60.196) 13:11 51 0
2893092 저도 전공자입니다만 [2] 루도그담당(118.235) 12:58 61 0
2893091 컴공전공은 전공했다는 사실이 중요한게 아님 [4] ㅇㅇ갤로그로 이동합니다. 12:45 108 1
2893090 array는 결국 포인터로 구현되는거아님? [3] 프갤러(223.39) 12:44 63 0
2893089 님들 학교 다닐때 30대있었음? [5] ㅇㅇ(117.53) 12:42 74 0
뉴스 김태호 PD, 광희 ‘고가 출연료’ 저격 “그 돈이면…” 디시트렌드 14:00
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2