Microsoft MVP성태의 닷넷 이야기
마샬링 정의 및 목적이 궁금합니다. [링크 복사], [링크+제목 복사],
조회: 9011
글쓴 사람
한예지 donator
홈페이지
첨부 파일
 

선생님 안녕하세요.
선생님 글들을 보았을 때 마샬링을 하는 경우가 크게 2가지로 정리할 수 있더라고요.
* Managed Memory에서 마샬링을 사용해 Unmanaged Memory로 옮길 때
* 스레드가 달라지면 마샬링을 하게 된다.

그래서 마샬링이 무엇인지 궁금해서 정의를 찾아보았습니다.
선생님 책에는 마샬링 정의가 없기 때문에 C++ 최적화[커트 건서로스] 412쪽을 참고했는데
다음과 같이 마샬링을 정의하고 있습니다.
"마샬링은 저장된 데이터를 전송 혹은 다른 매체에 저장 가능한 형태로 변환하는 것을 의미합니다."
읽어보면 직렬화와 비슷한 거 같아서 선생님 책에 직렬화 부분을 다시 읽어보았습니다.
"좁은 의미로 볼 때 일련의 바이트 배열로 변환하는 작업으로 바이트 배열은 직렬화 수단에 불과하다."
"넓은 의미에서 데이터를 어떤 것에 보관하고, 그것으로부터 복원만 할 수 있다면 그 모든 작업을 직렬화/역직렬화라고 정의할 수 있다."
다른 책이나 블로그를 참고해도 직렬화와 마샬링이 비슷하다고 느껴질 뿐 명확히 구분 지을 수 없었습니다.

그럼에도 불구하고 개인적으로 마샬링과 직렬화의 차이점을 추론하면

---------------------------------------------------------------
* 직렬화는 마샬링의 한 부분이다.
  프로세스 A의 객체 → (직렬화) → 직렬화된 데이터 → (마샬링) → 직렬화된 데이터 → (역직렬화) → 프로세스 B의 객체

* 마샬링은 코드베이스(원본 소스를 말한다)를 포함하여 객체를 직렬화 한다.
  class Student
  {
    public string Name;
    public int ID;
    // ...[생략]...
  }
  Student std = new Student("mijung", 23);
  직렬화는 객체의 필드에 저장된 값들을 메모리나 영구 저장 장치에 저장이 가능한
  0과 1의 순서로 바꾸는 것이기 때문에 "mijung, 23"이 직렬화 대상이 되는 것이고
  마샬링은 "mijung, 23"뿐만이 아니라 코드베이스인
  class Student
  { public string Name; public int ID; }도 같이 직렬화하는 것이다.
---------------------------------------------------------------

[질문 ①] 제가 직렬화와 마샬링 차이점을 요약한 것에 틀린 내용이 있을까요?

[질문 ②] 혹여나 제가 정리한 것이 맞더라도 선생님께서 생각하시는 마샬링의 정의와 목적이 궁금합니다.

[질문 ③] 스레드가 달라지면 마샬링을 하는 이유가 궁금합니다.
Managed Memory에서 마샬링을 사용해 Unmanaged Memory로 옮기는 경우라면
동일한 BOOL 타입이라도 C#인 경우와 C++인 경우 바이트가 달라서 마샬링이라는 것을 한다고 생각되는데
스레드가 달라지면 마샬링을 해야 되는 이유는 고민해 봐도 잘 모르겠습니다.








[최초 등록일: ]
[최종 수정일: 10/3/2023]


비밀번호

댓글 작성자
 



2023-10-04 01시23분
[답변 1, 2] 부끄럽지만 저도 ^^; 마샬링과 직렬화의 차이를 학술적으로 알고 있지는 않습니다. 개인적으로는, 우리의 직업을 "소프트웨어 개발자"라고 해야 할지, "소프트웨어 엔지니어"라고 해야 할지에 대한 차이와 비슷하다고 봅니다.

그래서 보통은 해당 용어를 사용하는 기술과 관련해 처음 문서를 접했을 때 봤던 용어를 그대로 관습적으로 사용하게 되는데, 가령 Win32 메시지를 전송할 때나 RPC 함수를 호출할 때는 인자를 마샬링한다고 표현하고, 파일이나 네트워크로 전송하기 위해 바이트 배열에 담을 때는 직렬화라고 쓰게 됩니다.

또한, 언급하신 "Managed Memory"에서 "Unmanaged Memory"로 옮길 때도 (역시 마이크로소프트의 문서에서 보게 된 기억으로) 마샬링이라는 단어를 쓰게 됩니다.

직렬화가 마샬링의 한 수단일 수 있다는 것에는 동의합니다. 가령, 아래의 객체를 "직렬화"한다고 하면,

    record class Person(int age, string name);
    Person my = new (5, "Tester");

보통은 5와 "Tester"라는 문자열을 그대로 보관하는 것을 가정하겠지만, 마샬링한다고 하면 상황에 따라 달라질 수 있습니다. 즉, InProcess 내에서 마샬링한다고 하면 그냥 참조 값을 전달할 것이고, OutOfProcess로 마샬링한다고 하면 직렬화에 준하는 방식으로 값을 전달하는 식으로 바뀔 수 있습니다.

그런데, "Codebase"를 같이 직렬화한다는 것은 다소 어색한 것 같습니다. 위의 사례에서 예로 든 Win32 메시지나 RPC 함수에서의 마샬링에서 Codebase 정보를 함께 전송하지는 않기 때문입니다. 찾아보니까 그에 대한 언급이 있던데,

What is the difference between Serialization and Marshaling?
; https://stackoverflow.com/questions/770474/what-is-the-difference-between-serialization-and-marshaling

저 질문의 답변자가 "Marshalling Object is serialized(member data is serialized) + Codebase is attached"라고 제약을 둔 것이 저도 잘 이해는 안 됩니다. 왜냐하면 실 사용예를 보면, 닷넷의 Binary Serialization과 같은 경우 직렬화한 데이터 내에 codebase 정보도 함께 넣기 때문에 이것을 반드시 마샬링의 영역이라기보다는 "필요 유무"에 따른 부가 정보라고 봐야할 것 같습니다. (참고로, 자바의 Log4j에 있었던 보안 결함도 직렬화에 포함된 codebase 정보가 연관된 것입니다.)

[답변 3] 스레드가 달라지면 마샬링을 하는 것은 상황에 따라 필요 유무가 달라질 수 있습니다. 해당 이야기에 대한 문맥 정보가 있다면 답변이 더 수월할 것 같지만, 일단 예전의 ActiveX/COM 개체를 예로 들면, 스레드가 다른 경우 STA COM 개체를 마샬링해 다른 스레드에 전달한 후 언마샬링해 써야 한다는 규칙이 있습니다.
정성태
2023-10-04 10시20분
스레드가 달라지면 마샬링을 하는 게시글은
https://www.sysnet.pe.kr/2/0/11679 에서 참고했습니다.

"우선, C# COM 객체는 기본적으로 COM Apartment 유형이 MTA입니다.
 이 때문에 STA에서 MTA COM 객체를 활성화한 경우 스레드가 달라지면 마샬링을 하게 됩니다.
 이때의 마샬링이란 콜백 이벤트의 호출을 직렬화하기 위해 Win32 이벤트를 사용한다는 것입니다."

그리고 선생님의 답변을 보고 다른 곳에서도 그런 글이 있는지 찾아보았습니다.
스레드가 달라지면 마샬링을 할 수"도" 있다는 냄새(?)를 풍기는 문장이 있습니다.

"윈폼 (WinForms)에는 System.Windows.Forms.Timer라는 클래스가 있으며,
이들 타이머 클래스들은 Tick 이벤트 핸들러를 실행하기 위해 별도의 작업쓰레드를 생성하지 않고
UI 쓰레드에서 실행하기 때문에,
UI 컨트롤이나 UI Element들을 직접 이벤트 핸들러 안에서 마샬링 없이 엑세스할 수 있다."
[출처] https://www.csharpstudy.com/Threads/timer.aspx

위의 글을 보면 만약 작업스레드를 생성해서 실행하는 경우
마샬링을 하면 UI 컨트롤이나 UI Element들을 접근할 수 있다고 해석할 수"도" 있습니다.

서로 다른 프로세스도 아니고 같은 솔루션 파일 안에서 스레드만 다를 뿐인데
왜 직렬화를 해야 되는지 이해가 되지 않습니다.
저는 같은 솔루션 파일 안이면 당연히 Managed Memory, Unmanaged Memory도 상관없고
같은 솔루션에 있는 스레드'들'이라면 데이터 타입도 동일하게 맞출 수 있을 텐데
굳이 마샬링을 해야 되나 싶습니다...
한예지
2023-10-05 12시18분
11679 글은 COM 개체이기 때문에 그런 것입니다.

인용하신 csharpstudy 글의 "마샬링"의 경우에는 데이터가 아닌 (어찌보면 마찬가지로 데이터에 불과한) 코드를 마샬링한다고 보면 되겠습니다. 즉, 실행해야 할 코드의 주소를 현재 스레드에서 실행하지 않고 다른 스레드에서 실행할 수 있도록 Control.Invoke 또는 Control.BeginInvoke를 통해 마샬링시켜서 전달하는 것입니다. (실제로는 코드 주소 그대로 전달되겠지만 대상 스레드가 실행하도록 부가 처리가 되는 정도입니다.)

"위의 글을 보면 만약 작업스레드를 생성해서 실행하는 경우 마샬링을 하면 UI 컨트롤이나 UI Element들을 접근할 수 있다고 해석할 수도 있다"고 언급하셨는데, 실제로 접근할 수 있게 돼 있습니다. 그 예제를 아래의 글에서 다루고 있습니다.

UI 요소의 접근은 반드시 그 UI를 만든 스레드에서!
; https://www.sysnet.pe.kr/2/0/11561

UI 요소의 접근은 반드시 그 UI를 만든 스레드에서! - 두 번째 이야기
; https://www.sysnet.pe.kr/2/0/12537

다시 반복이 되는 듯합니다. 그러니까 결국 11561, 12537 글에 대해서 잘 이해가 안 된다는 것인가요?

(개인적으로는, Invoke/BeginInvoke 호출에 전달하는 것을 마샬링이라는 어려운 용어로 표현하지는 않고, "UI 접근 코드를 태워서 실행"한다는 식으로 표현합니다: "https://www.sysnet.pe.kr/2/0/11071#run_async")
정성태
2023-10-05 09시09분
11561, 12537 글을 선생님이 어떤 목적을 가지고 작성하셨는지는 이해하고 있습니다.
  
이번 주 금, 토, 일에 도서관 가서 다양한 책을 읽어본 후에 선생님 답변 다시 한번 읽어보도록 하겠습니다^^

답변 감사드립니다!
한예지
2023-10-05 11시28분
개발 관련 용어들 중에서 보면 한글화가 딱히 어려운 것들이 있는 듯합니다. Marshal이 그렇고, 제 경험으로는 Bind도 "묶는다"라는 식으로 억지 번역을 할 수 있겠지만 대개의 경우에는 그냥 '바인드'라고 쓰는 것이 더 좋았습니다. 예를 들어, 소켓을 지정한 IP/Port에 바인딩한다고 하면 자연스러운데, 묶는다... 또는 엮는다라고 하면 왠지 ^^; 감이 살지 않습니다.

그래도 결국 나중에는 바인딩의 문맥상 의미를 알게 되는 것처럼, 마샬링도 유사할 거라 봅니다. 오죽했으면 그 stackoverflow의 질문처럼 외국인들도 Q&A를 할 정도이니 한국인이 어려워하는 것은 당연한 듯합니다. 너무 조급하게 생각하지 마시고 현재의 쓰임 용도만 숙지한 체로 자연스러운 시간과 경력의 흐름에 맡기는 것도 좋겠습니다.
정성태

1  [2]  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
5931이대희4/2/20245396Windows 앱 SDK C# 템플릿의 용도가 무엇인지요? [1]
5930vict...2/22/20246733ef core, FromSqlRaw 맵핑 질문입니다. [4]
5929a2/17/20245971.Net 8 에서 디버거 변경 [1]
5928vict...2/5/20247078wpf에서 대량 데이터 보여주는 방법 추천 부탁드립니다. [1]
5926엄태영1/12/20247311잘못된 Task 사용으로 인한 데드락 관련 질문 입니다. [3]
5925Euni...12/22/20236568Visual Studio에서 nodejs 사용시 npm install -g @vue/cli 실행시 오류 [1]
5924Euni...12/21/20236760Visual Studio에서 nodejs 사용시 C:\Program Files\nodejs\\node.exe" "C:\Program Files\nodejs\\node_modules\npm\bin\npm-cli.js" prefix -g 를 찾지 못하는 설치 오류 [2]
5923정두호12/4/20237173MSSQL 데이터 전송과 공유폴더의 데이터 전송 차이점 [1]
5922Heeg...10/27/20239479C++의 double pointer를 C#에서 구현하는 방법이 잘 안됩니다. [3]
5921한예지 donator10/3/20239011마샬링 정의 및 목적이 궁금합니다. [5]
5920한예지 donator10/3/20238228C#과 WIN32 API 관계 질문드립니다. [4]
5919이건우9/27/20237671WinForm의 로딩속도 관련 질문입니다 [2]
5917한예지 donator9/14/20237672동기화 도구 질문 있습니다. [4]
5916한예지 donator9/3/20238098Thread.Sleep(500), await Task.Delay(500), Task.Delay(500) 차이점이 궁금합니다. [2]
5915한예지 donator8/30/20238166비동기 코드를 for 문 안에 작성한 경우 제어 변수가 올바르게 동작하지 않는 이유가 궁금합니다. [3]
5914한상욱8/11/20237894.net wpf에서 skiasharp 의 skelement 를 canvas로 사용 하고 있습니다. [1]
5913김태우8/10/20237820지역변수로 이해하는 메서드매개변수 게시글 댓글 [3]
5912guest4/25/202312633[참고 - 초보용] Sqlite 디비는 double이 없고 Real이 대신합니다 [3]
5911guest4/24/20238243Form1.cs와 외부 class.cs와 통신 (static async method포함) [4]파일 다운로드1
5910guest4/24/20238040Async 메서드와 try~catch [1]
5909guest4/22/20238675Visual Studio 구매 시(1인 개발자) [4]
5908guest4/22/20238491텅빈 원그리기 [5]
5907민성4/21/20237890안녕하세요 서버 백업 문제에 대해서 [2]
5906guest4/21/20238164Dispatcher 서비스 구현 질문 [1]
5905guest4/20/20238910tabControl의 tabPage가 여러 개일 때 순서를 바꾸기가 까다롭네요 [5]
5904guest4/18/20238797[신규자료첨부] DLL 'SQLite.Interop.dll'을 찾을 수 없습니다 [4]파일 다운로드1
1  [2]  3  4  5  6  7  8  9  10  11  12  13  14  15  ...