원문 출처 : 당근로리야스님 블로그 (http://blog.danggun.net/799)

 

클래스 마샬링을 할일이 없엇 신경을 안쓰다가 요번에 스카이프 api나 제가 직접 마샬링 해볼까 해서 클래스 마샬링을 정리해 보았습니다.

근데 왜이렇게 자료가 없지?
겨우 찾은것이 비주얼C++ 팀블로그인데....네...영어입니다 ㅡ.-;
(참고 : Visual C++ Team Blog - Inheriting From a Native C++ Class in C#)

일단 변환방법이 마음에 들지가 않아서 위글에 있는 내용을 그대로 사용하여 만들고 자료를 더 찾는다면 파트2로 돌아오 겠습니다 ㅎㅎㅎㅎ
그전에 이 글은 크게 2부분으로 나누어 설명할 예정입니다.

어찌됬건 프로그래머라면 일단 샘플부터 만들고 생각해야 하지 않겠습니까?

 
1. C++ DLL 만들기

C#에서 노출 시킬 클래스가 담겨있는 C++ DLL을 만들겠습니다.

1-1.프로젝트 생성

프로젝트 이름은 꼭 "cppexp"로 합니다.
진입점 문제 때문인데 해결방법은 있으나....좀더 편한 테스트 환경을 위해 "cppexp"로 합니다 ㅎㅎㅎ



1-2.코드 넣기(CSimpleClass.h)

클래스 이름도 "CSimpleClass"로 바꿔 줍니다.
샘플 코드와 마찬가지로 저도 해더에 모든  코드를 넣습니다.

아래 코드는 전체 코드입니다-_-;
잘 모고 따라하시길 ㅎㅎㅎ

// cppexp.h
#include <stdo.h>
#pragma once
 
using namespace System;
 
class __declspec(dllexport) CSimpleClass {
public:
      int value;
      CSimpleClass(int value) : value(value)
      {
      }
      ~CSimpleClass()
      {
            printf("~CSimpleClass\n");
      }
      void M1()
      {
            printf("C++/CSimpleClass::M1()\n");
            V0();
            V1(value);
            V2();
      }
      virtual void V0()
      {
            printf("C++/CSimpleClass::V0()\n");
      }
      virtual void V1(int x)
      {
            printf("C++/CSimpleClass::V1(%d)\n", x);
      }
      virtual void V2()
      {
            printf("C++/CSimpleClass::V2()\n", value);
      }
};

빌드를 돌려보면 별다른 문제 없이 dll이 생성됩니다.

여기서 생성된 "cppexp.dll", "cppexp.lib" 이 두개 파일이 중요합니다.

2. C# 샘플 만들기
이 샘플코드를 사용하기 위해서는 C#쪽에서 해야할 작업이 많습니다.
프로젝트는 아무것이나 상관없으나 이샘플자체가 콘솔응용프로그램이므로 'C# 콘솔 응용프로그램'으로 프로젝트를 생성합니다.

2-1. CSimpleClass 클래스 생성
cppexp.dll를 직접 핸들릴할 클래스입니다.

아래코드는 클래스의 전체 코드입니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
 
namespace ConsoleApplication1
{
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public unsafe struct __CSimpleClass
    {
        public IntPtr* _vtable;
        public int value;
    }
 
    public unsafe class CSimpleClass : IDisposable
    {
        private __CSimpleClass* _cpp;
 
        // CSimpleClass constructor and destructor
        [DllImport("cppexp.dll", EntryPoint = "??0CSimpleClass@@QAE@H@Z", CallingConvention = CallingConvention.ThisCall)]
        private static extern int _CSimpleClass_Constructor(__CSimpleClass* ths, int value);
        [DllImport("cppexp.dll", EntryPoint = "??1CSimpleClass@@QAE@XZ", CallingConvention = CallingConvention.ThisCall)]
        private static extern int _CSimpleClass_Destructor(__CSimpleClass* ths);
        
        //      void M1();
        [DllImport("cppexp.dll", EntryPoint = "?M1@CSimpleClass@@QAEXXZ", CallingConvention = CallingConvention.ThisCall)]
        private static extern void _M1(__CSimpleClass* ths);
 
        public CSimpleClass(int value)
        {
            //Allocate storage for object
            _cpp = (__CSimpleClass*)Memory.Alloc(sizeof(__CSimpleClass));
            //Call constructor
            _CSimpleClass_Constructor(_cpp, value);
        }
        public void Dispose()
        {
            //call destructor
            _CSimpleClass_Destructor(_cpp);
            //release memory
            Memory.Free(_cpp);
            _cpp = null;
        }
        public void M1()
        {
            _M1(_cpp);
        }
    }
}


"??0CSimpleClass@@QAE@H@Z"와 같은 알수 없는 코드들은 코드의 진입점입니다-_-;
이 방법으로 클래스를 마샬링 하기 위해서는 위와같이 진입점 코드가 있어야 합니다.
진입점 코드는 어떻게 찾느냐? 아까 말했던 .lib파일을 메모장으로 열어보시면 나와 있습니다.

0CSimpleClass : 0클래스 이름 이 생성자
1CSimpleClass : 1클래스 이름 이 파괴자
나머지 함수들은 이름으로 검색하면  코드를 알수 있습니다.

이 클래스를 만들면 "Memory.Alloc"와 "Memory.Free" 같은 곳에서 에러가 납니다.
"Memory"라는 클래스가 없기 때문이죠 ㅎㅎㅎ


2-2. Memory 클래스 생성

Memory이 클래스는 내용이 어떤것인가 하고 찾아보았습니다.
C#에서 동적 메모리 할당을 위해 사용하는 클래스 샘플입니다.

닷넷에서는 메모리관리는 특별한 경우를 제외하면 가비지컬랙터가 처리합니다.
이 가바지컬랙터를 거치지 않고 사용할수 있게 하는 샘풀이죠.
말이 샘플이지 이대로 쓰는대 전혀 손색이 없습니다.

참고 : MSDN - A.8 동적 메모리 할당

아래 코드는 클래스 전체 코드 입니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    using System;
    using System.Runtime.InteropServices;
    public unsafe class Memory
    {
        // Handle for the process heap. This handle is used in all calls to the
        // HeapXXX APIs in the methods below.
        static int ph = GetProcessHeap();
        // Private instance constructor to prevent instantiation.
        private Memory() { }
        // Allocates a memory block of the given size. The allocated memory is
        // automatically initialized to zero.
        public static void* Alloc(int size)
        {
            void* result = HeapAlloc(ph, HEAP_ZERO_MEMORY, size);
            if (result == null) throw new OutOfMemoryException();
            return result;
        }
        // Copies count bytes from src to dst. The source and destination
        // blocks are permitted to overlap.
        public static void Copy(void* src, void* dst, int count)
        {
            byte* ps = (byte*)src;
            byte* pd = (byte*)dst;
            if (ps > pd)
            {
                for (; count != 0; count--) *pd++ = *ps++;
            }
            else if (ps < pd)
            {
                for (ps += count, pd += count; count != 0; count--) *--pd = *--ps;
            }
        }
        // Frees a memory block.
        public static void Free(void* block)
        {
            if (!HeapFree(ph, 0, block)) throw new InvalidOperationException();
        }
        // Re-allocates a memory block. If the reallocation request is for a
        // larger size, the additional region of memory is automatically
        // initialized to zero.
        public static void* ReAlloc(void* block, int size)
        {
            void* result = HeapReAlloc(ph, HEAP_ZERO_MEMORY, block, size);
            if (result == null) throw new OutOfMemoryException();
            return result;
        }
        // Returns the size of a memory block.
        public static int SizeOf(void* block)
        {
            int result = HeapSize(ph, 0, block);
            if (result == -1) throw new InvalidOperationException();
            return result;
        }
        // Heap API flags
        const int HEAP_ZERO_MEMORY = 0x00000008;
        // Heap API functions
        [DllImport("kernel32")]
        static extern int GetProcessHeap();
        [DllImport("kernel32")]
        static extern void* HeapAlloc(int hHeap, int flags, int size);
        [DllImport("kernel32")]
        static extern bool HeapFree(int hHeap, int flags, void* block);
        [DllImport("kernel32")]
        static extern void* HeapReAlloc(int hHeap, int flags,
           void* block, int size);
        [DllImport("kernel32")]
        static extern int HeapSize(int hHeap, int flags, void* block);
    }
}
코드에 [DllImport("kernel32")]가 있는데 이소리는 커널을 불러다 사용한다는 소리입니다.
운영체제에 따라 작동안할수도 있다는 것입니다 ㅡ.-;;

어찌됬건 이렇게 "Memory"라는 클래스를 만들고 유징하시면 에러는 사라 집니다.

2-3.테스트 코드
이제 준비가 끝났습니다.
2-1.에서 'M1()' 만 마샬링을 해두었으므로 'M1()'만 호출이 가능합니다.

프로그램의 진입점인 'Main()'으로 가서 다음 코드를 추가 합니다.


CSimpleClass sc = new CSimpleClass(10);
using (sc)
{
    //M1 calls all of the virtual functions V0,V1,V2
    sc.M1();
}


3.확인
빌드를 돌리면 
"Unsafe code may only appear if compiling with /unsafe"
이런 에러가 납니다.
비관리 코드를 사용하기위한 옵션을 켜라는 소리입니다 ㅡ.-;;

3-1.비관리 코드 사용 옵션
프로젝트 속성 > 빌드 > 안전하지 않는 코드 허용
옵션을 켜줍니다.



 
3-2. 출력 확인
화면이 순식간에 꺼진다면 알아서 화면 챙기시고 ㅋㅋㅋㅋ(그냥 중단점만 걸어도 됩니다-_-a)


정확하게 출력 되는 것을 볼수 있습니다.

5.마무리
위에 내용들을 정확하게 이해했다면 샘플에 나와있는 다른 클래스 맴버들도 마샬링을 할수 있습니다.
당연한 이야기지만 클래스는 무조건 통으로 마샬링해야 합니다.
안그러면 사용을 할수 없어요.


샘플 프로젝트

 

 Projects.zip

 

 

 

가볍게 쓸 파일DB로 SQLite를 추천받아서 하루이틀 정도 자료를 봤는데..

솔찍히 국내 자료에서는 바로 갖다 쓰기 쉽게끔 되어있는 예제나 샘플코드가 없더군요.


뭐.. 블로그나 포럼에서 원론적인 강좌는 몇몇 있긴 한데, 예제로 작성한 코드에서 가타부타 설명도 없이 튀어나오는

컨트롤 변수 같은것도 많고, 결과적으로 바로 컴파일해서 직접 분석해볼 수 있는 풀 소스 코드도 없었습니다.


결국 코드프로젝트와 기타 자료들을 정리해서 SQLite 샘플을 만들었습니다.

기본적이지만 꼭 필요한 기능만 넣어뒀고, 아마 예제코드만 대강 훑어보셔도 '아 SQLite는 이렇게 쓰는거구나' 하고 알 수 있지 않을까 싶습니다.




SQLiteSample_src.zip

SQLiteSample_bin.zip



예제 소스코드는 VS2010을 사용하여 C# 기반으로 작성되었습니다.


사용한 예제 DB는 하나의 테이블에 9개의 필드로 구성되어 있습니다.



 항 목

상 세 

 테이블 명

Table_Env 

 필드

 Scenario_name

 char(30)

 Env_Location

int 

 Env_Season

 int

 Env_Weather

 int

 Env_TimeOfDay

int 

 Env_CloudLow

double 

 Env_CloudHigh

double 

 Env_CloudQuantity

int 



바이너리 파일을 실행하면 다음과 같은 간단한 폼이 뜹니다.




순서대로 DB파일 오픈, 항목 추가, 항목 내용 갱신, 시나리오명으로 항목 찾기, 항목 삭제 버튼입니다.

예제 소스코드를 보시면 내용이 매우 간단하게 구성되어 있습니다.


항목의 갱신이나 찾기, 삭제 시 DataGridView의 첫번째 열 정보인 시나리오명을 기준으로 작업을 수행합니다.

DB를 각자 필요에 의해 구성하실때 보통 필드 첫 열은 Index number로 하는 경우가 많으니 그 부분은 각자 재량껏 수정하시면 되리라 생각됩니다.


일단 예제 만들어 두고 저도 까먹으면 갖다쓰려고 포스팅 하는거라 그다지 주절주절 더 쓸 말이 없네요.


음.. 그럼 이만 뿅~☆

개발 시 자주 쓰지만, 한동안 안쓰다 또 쓰려면 까먹고 또 자료 찾아보려면 그게 여간 귀찮은게 아닌지라

제가 자주 쓰는 모듈들을 레퍼런스 클래스 하나로 묶어버렸습니다.


버그 수정 및 예제 프로그램 작성 등 버전 1.03으로 업데이트 합니다.




PreDefined.h


 각 모듈에서 필요에 따라 재정의할 것들을 선정의 해놓은 헤더.


CloudTree.h

 

 CloudTree 클래스와 각 모듈에서 필요한 클래스 정의가 들어있는 헤더. 

 

CloudTree.cpp


 CloudTree 클래스와 각 모듈이 구현되어 있는 소스파일.


소스코드가 있는 폴더에 위 세파일 복사하고, class view에서 각 파일 등록해준 후 쓰면 됩니다.

당연한 말이지만, Cloudtree 클래스 포인터 선언할 곳에 #include "CloudTree.h" 포함하는건 기본 센스아니겠습니까 ㅎㅎ


version : 1.03

date : 2016. 3. 21


포함하고 있는 함수 목록

  • Eucledian Distance(2D/3D) - xy 2차원 좌표간 거리 / xyz 3차원 좌표간 거리
  • 가우시안 랜덤 함수 - 중심값과 표준편차를 설정하여 가우시안 랜덤값을 발생시키는 함수
  • 공유메모리 할당 / 해제 함수
  • 공유메모리 할당 / 해제 간소화 함수 (유져 편의성)
  • TCP/IP 서버-클라이언트 함수 (수정)
  • 위경도 이용하여 정북 기준으로 방위각 구하는 함수
  • 위경도 이용하여 두 지점 사이의 거리를 구하는 함수
  • ECEF(지구중심좌표계) 좌표를 위경고도로 변환하는 함수
  • 클럭 타이머를 이용한 경과시간 체크 함수
  • 크리티컬 섹션 잠금/해제



이렇게까지 설명해줬는데 행여라도 어떻게 쓰는지 모른다는 분이 계실까봐 써보는 간단한 활용 예제.


  CloudTree * cloudtree new CloudTree ();
  cloudtree->CreateSharedMemSimple();
  cloudtree->DestroySharedMemSimple();


Cloudtree형 클래스 포인터 하나 만들어서 각 모듈 불러오면 됩니다.

공유메모리 모듈의 경우 두가지가 있는데, 일반 모듈은 직접 정의해서 쓰고 싶을때 쓰시고 Simple 붙은 모듈은 그냥 호출만 하시면 PreDefined.h에 정의된 stShareData 구조체의 포인터 m_pShared를 통해 공유 메모리에 접근할 수 있습니다.

stShareData 구조체는 필요에 따라 각자 알아서 수정해서 쓰시면 됩니다.


이래도 사용하는데 어려움을 느끼시는 분이 계신다고 하시면..



구름나무 레퍼런스 클래스 v1.02 예제 프로그램과 소스코드


Reference_class_sample.exe


 구름나무 레퍼런스 클래스 기능 구현 예제 프로그램.


Reference_class_sample_v103.zip


 구름나무 레퍼런스 클래스 기능 구현 예제 소스코드. 



예제 프로그램과 소스코드를 보시면 아마 이해가 빠르시지 않을까 싶습니다.

예제 소스코드는 VS2010 기준으로 작성되었습니다.


이하는 예제 프로그램 화면입니다.

기능은 프로그램 상에서 충분히 이해하기 쉽도록 구성되어 있다 생각합니다.









그럼 v1.03 게시물은 이만 총총~

구름나무가 자주 쓰지만, 한동안 안쓰다 또 쓰려면 까먹고 귀찮아서 자주 쓰는 모듈들을 레퍼런스 클래스 하나로 묶어버렸습니다.

버그 수정 및 예제 프로그램 작성 등 버전 1.02로 업데이트 되어 포스팅합니다.




PreDefined.h


 각 모듈에서 필요에 따라 재정의할 것들을 선정의 해놓은 헤더.

 

CloudTree.h


 CloudTree 클래스와 각 모듈에서 필요한 클래스 정의가 들어있는 헤더. 

 

CloudTree.cpp


 CloudTree 클래스와 각 모듈이 구현되어 있는 소스파일.


소스코드가 있는 폴더에 위 세파일 복사하고, class view에서 각 파일 등록해준 후 쓰면 됩니다.

당연한 말이지만, Cloudtree 클래스 포인터 선언할 곳에 #include "CloudTree.h" 포함하는건 기본 센스아니겠습니까 ㅎㅎ


version : 1.02

date : 2016. 3. 16


포함하고 있는 함수 목록

  • Eucledian Distance(2D/3D) - xy 2차원 좌표간 거리 / xyz 3차원 좌표간 거리
  • 가우시안 랜덤 함수 - 중심값과 표준편차를 설정하여 가우시안 랜덤값을 발생시키는 함수
  • 공유메모리 할당 / 해제 함수
  • 공유메모리 할당 / 해제 간소화 함수 (유져 편의성)
  • TCP/IP 서버-클라이언트 함수
  • 위경도 이용하여 정북 기준으로 방위각 구하는 함수
  • 위경도 이용하여 두 지점 사이의 거리를 구하는 함수
  • ECEF(지구중심좌표계) 좌표를 위경고도로 변환하는 함수
  • 클럭 타이머를 이용한 경과시간 체크 함수



이렇게까지 설명해줬는데 행여라도 어떻게 쓰는지 모른다는 분이 계실까봐 써보는 간단한 활용 예제.


  CloudTree * cloudtree new CloudTree ();
  cloudtree->CreateSharedMemSimple();
  cloudtree->DestroySharedMemSimple();


Cloudtree형 클래스 포인터 하나 만들어서 각 모듈 불러오면 됩니다.

공유메모리 모듈의 경우 두가지가 있는데, 일반 모듈은 직접 정의해서 쓰고 싶을때 쓰시고 Simple 붙은 모듈은 그냥 호출만 하시면 PreDefined.h에 정의된 stShareData 구조체의 포인터 m_pShared를 통해 공유 메모리에 접근할 수 있습니다.

stShareData 구조체는 필요에 따라 각자 알아서 수정해서 쓰시면 됩니다.


이래도 사용하는데 어려움을 느끼시는 분이 계신다고 하시면..



구름나무 레퍼런스 클래스 v1.02 예제 프로그램과 소스코드


Reference_class_sample.exe


 구름나무 레퍼런스 클래스 기능 구현 예제 프로그램.

 

Reference_class_sample_v1.02.zip


 구름나무 레퍼런스 클래스 기능 구현 예제 소스코드. 


예제 프로그램과 소스코드를 보시면 아마 이해가 빠르시지 않을까 싶습니다.

그럼 v1.02 게시물은 이만 총총~


한동안 안쓰다 또 쓰려면 까먹고 귀찮아서 자주 쓰는 모듈들을 개인용 클래스 하나로 묶어버렸습니다.

소소한 버전업으로 업로드 합니다.



PreDefined.h

 

 각 모듈에서 그때그때 필요에 따라 재정의할 것들만 밖으로 빼놓은 헤더.


CloudTree.h


 CloudTree 클래스와 각 모듈에서 필요한 클래스 정의가 들어있는 헤더. 


CloudTree.cpp


 CloudTree 클래스와 각 모듈이 구현되어 있는 소스파일.


소스코드가 있는 폴더에 위 세파일 복사하고, class view에서 각 파일 등록해준 후 쓰면 됨.

당연한 말이지만, Cloudtree 클래스 포인터 선언할 곳에 #include "CloudTree.h" 포함하는건 기본 센스아니겠음?!


version : 1.01

date : 2016. 3. 15


포함하고 있는 함수 목록

  • Eucledian Distance - xy 2차원 좌표간 거리 / xyz 3차원 좌표간 거리
  • 가우시안 랜덤 함수 - 중심값과 표준편차를 설정하여 가우시안 랜덤값을 발생시키는 함수
  • 공유메모리 할당 / 해제 함수
  • 공유메모리 할당 / 해제 간소화 함수 (유져 편의성)
  • 클럭 타이머를 이용한 경과시간 체크 함수
  • TCP/IP 서버-클라이언트 함수
  • 위경도 이용하여 정북 기준으로 방위각 구하는 함수
  • 위경도 이용하여 두 지점 사이의 거리를 구하는 함수
  • ECEF(지구중심좌표계) 좌표를 위경고도로 변환하는 함수



이렇게까지 설명해줬는데 행여라도 어떻게 쓰는지 모른다는 사람이 있을까봐 써보는 간단한 활용 예제.


  CloudTree * cloudtree new CloudTree ();
  cloudtree->CreateSharedMemSimple();
  cloudtree->DestroySharedMemSimple();


Cloudtree형 클래스 포인터 하나 만들어서 각 모듈 불러오면 됩니다.

공유메모리 모듈의 경우 두가지가 있는데, 일반 모듈은 직접 정의해서 쓰고 싶을때 쓰시고 Simple 붙은 모듈은 그냥 호출만 하시면 PreDefined.h에 정의된 stShareData 구조체의 포인터 m_pShared를 통해 공유 메모리에 접근할 수 있습니다.

stShareData 구조체는 필요에 따라 각자 알아서 수정해서 쓰시면 됩니다.

OMG DDS Portal
http://www.omgwiki.org/dds/tutorials
... OMG 에서는 DDS 표준의 산업계 활성화를 위해 포털을 제공하고 있다.
특히, 튜토리얼이 잘 제공되고 있으므로 원하는 목적에 맞는 활용법이 뭔지 관련 자료를 찾아볼 수 있다.


The Data Distribution Service for Real-Time Systems: Part 1
http://www.drdobbs.com/architecture-and-design/222900238
... DDJ에 소개된 DDS에 대한 이해.

[PPT] An Overview of the OMG DDS - Washington University in St. Louis
http://www.cs.wustl.edu/~schmidt/DDS.ppt
... OMG의 DDS에 대한 설명. 워싱턴 대학의 DOC 그룹을 주관하는 Schmodt 교수 제공 자료.

OpenDDS
http://www.opendds.org
... OpenDDS는 실시간으로 데이터를 여러 곳에 분배하고 동기화 할 수 있는 데이타 분산 미들웨어의 표준인 DDS(Data Distribution Service) 스펙을 구현한 오픈소스 미들웨어이다. DDS는 OMG를 통해 실시간 데이터 분산 분야의 미들웨어로 표준화 되었다.
... DDS를 잠깐 시험해본 소감으로는 이벤트에 실어보낼 데이터 타입을 정의하는데 CORBA에서 사용하는 IDL을 사용한다. IDL의 기능 중 데이터만 정의하는 것으로, CORBA와 달리 원격 오퍼레이션 부가 없기 때문에 데이터 전달 속도가 상당히 빠르다. 원격 오퍼레이션 부가 없기 때문에 구현이 여러가지 언어로 될 수 있고 적은 메모리 풋프린트를 요구한다.(내장형 실시간 시스템에 딱이다!) 주로 센서 네트워크나 레이더에서 데이터를 수집해오고 필터링 하는 곳에 쓰이며, DSP에 포팅된 사례도 있다.

OpenDDS 소스 및 매뉴얼
http://download.ociweb.com/OpenDDS/
... OpenDDS는 C++ 바인딩이 기본이지만 Java 바인딩도 지원한다. 사용할 수 있는 데이타타입은 tao_idl 컴파일러로 생성한다. (단, DDS 전용 옵션인 "-Gdcps"을 줘서 컴파일한다.) C++ 코드와 Java 코드가 동시에 생성되는데 C++ 코드는 컴파일해서 공유라이브러리로, Java 코드는  jar로 묶어서 사용자가 짠 Java코드와 함께 배포하면 된다. OpenDDS의 Java 바인딩은 JNI를 통한 방식이다. JNI용 C++ 코드와 Java 코드가 tao_idl 컴파일러에서 자동 생성되므로 사용자는 OpenDDS의 publisher, subscriber 가 되는 방법을 이해하고 메시지와 QoS를 취급할 줄 알면된다. 순수하게 C++로 코드를 짜고자 하는 경우 TAO와 ACE 라이브러리가 필요하다.
... 시간이 되면 구글폰이나 삼성의 바다폰에 OpenDDS를 이용할 수 있으면 어떨까 싶은 생각이 든다. DDS는 OMG가 정한 메시징 미들웨어의 국제표준이며, 프로토콜중 하나는 표준으로 정해져 있고, 특히, OpenDDS는 DDS 제품들중 프로토콜 확장 구조를 맨 처음 사용하였고고 OMG와 관련 업계에 공개하여 표준화에 기여한 바가 크다. 센서나 레이더 같은 장치에서 실시간으로 시간지연 오차를 최소화하면서 데이터를 보내고 필터링하는 경우 DDS의 전망과 활용가치는 매우 크다.

DDS와 대외계 시스템
http://blog.smallake.kr/smallake/448
... 알티베이스의 역사와 대외계에 AltiBase사에서 DDS 제품을 표준으로 사용하려는 시도에 대한 고찰

gCitizen: A Grid Middleware for a Transparent
Management of the Information about Citizens in the Public Administration
http://www.jtaer.com/apr2007/dealfonso_caballer_carrion_hernandez_p2.pdf
... DDS, 서비스 호출을 혼성하여 시민을 위한 정보서비스를 관리하는 그리드 미들웨어 프레임워크
대개 미들웨어 들은 기능을 다루는 경우가 많은데, 대민 서비스를 상대로 응용되는 것을 설명한 드문 경우라서 참고해볼 필요가 있다.

Data Distribution Service as an alternative to CORBA Notification Services for the Alma Common Software
http://icalepcs2009.spring8.or.jp/abstract/pdf/WEA006_TALK.PDF
... 더 자세한 정보는 http://www.eso.org/projects/alma/develop/acs

Publish/Subscribe Internetworking
http://www.uio.no/studier/emner/matnat/ifi/INF5090/v09/undervisningsmateriale/INF5090-Pub-Sub-2009-Oslo.pdf
... DDS와 JMS 인터워킹에 대한 설명.

A QoS Policy Configuration Modeling Language for
Publish/Subscribe Middleware Platforms
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.77.3016&rep=rep1&type=pdf

Workshop on Distributed Object Computing for Real-time and Embedded Systems
July 14 – 16, 2008, Washington, DC, USA
http://www.omg.org/news/meetings/realtime2008/Program.htm
... 2008년 OMG의 Realtime2008 에서는 DDS에 대한 튜토리얼, 고급 이슈들이 많이 다루어졌다.

OMG Standards in Government & NGO's Workshop
July 13-15, 2009, Westin Arlington Gateway, Arlington, VA USA
http://www.omg.org/news/meetings/GOV-WS/rte/Program.htm
... 2009년 OMG의 Realtime2008 에서도 역시 DDS에 대한 튜토리얼, 고급 이슈들이 많이 다루어졌다.

Model-Based Autosynthesis of Time-Triggered Buffers for
Event-Based Middleware Systems
http://www.dsmforum.org/events/DSM09/Papers/Sprinkle.pdf
... An advantage of domain-speci c modeling is the ability to refactor an application to include time-triggered, event-based schedulers. In this paper we present an application in need of such modi cation, and discuss how these additional blocks must be synthesized in order to conform to the input/output constraints of the existing diagram.

Future of CORBA for Distributed Real-time & Embedded Systems
http://www.dre.vanderbilt.edu/~schmidt/ICALEPCS.ppt
... CORBA와 DDS는 분산시스템을 위해 OMG가 정의한 양대 표준인데, 그동안 군에서는 CORBA가 주로 사용되어 왔으며, 나름 단점도 있었다. DDS가 이를 보완하는 용도로 적합하며 미래는 둘이 상호보완되어 결합되는 형태로 발전할 것이다.

Hybernating DDS with C++ and Java
http://www.slideshare.net/Angelo.Corsaro/hibernating-dds
... DDS에 DBMS로 데이타 매핑을 하여 하이버네이트 시키는 구조에 대한 이해

OMG Modeling Specifications
http://www.aswec2008.curtin.edu.au/OMG%20Modeling%20Specifications.ppt
... OMG의 여러가지 모델링 표준에 대한 튜토리얼

Data distribution service and database management systems bridge
United States Patent 7533128

http://www.freepatentsonline.com/7533128.html
... DDS와 DBMS 시스템간 브리지에 특허가 걸려있다. 이 구조와 유사하게 가지 않도록 유의한다.

Distributed Event-based Systems (Hardcover)   
Muhl, Gero, Fiege, Ludger, Pietzuch, Peter  저 | Springer-Verlag New York Inc | 2007.03.05
http://book.naver.com/bookdb/book_detail.nhn?bid=2818334
... 정말 오랫만에 이벤트 기반 분산 시스템에 대해 정리된 책이 나왔다. 미들웨어를 연구하는 사람이라면 꼭 봐두어야 할 내용 아닐까 싶다.