AutoCAD 플러그인을 개발하면서 항상 고민이 되는 부분이
어떻게 Host 어플리케이션과 연동하는냐하는 문제였습니다.
초기에는 윈도위 API인 SendMessage를 이용하여 서로 데이타를 주고 받도록 디자인을 했었는데 뭔가 밀접하게 연결이 되어 있지 않다는 느낌이 강했습니다.
그래서 Tcp/IP 통신을 이용하여 상호 연동하는 방식으로 변경하기로 했습니다.
AutoCAD에 플러그인이 로딩됨과 동시에 Tcp/IP로 Host 어플리케이션이 접속하기를 기다립니다.
데이타는 DataSet을 이용하여 서로 주고 받도록 하였습니다.
이렇게 플러그인이 로딩되고 난 뒤에,
Host 어플리케이션이 플러그인에 접속해서 데이타를 주고 받을 수 있습니다.
어떻게 Host 어플리케이션과 연동하는냐하는 문제였습니다.
초기에는 윈도위 API인 SendMessage를 이용하여 서로 데이타를 주고 받도록 디자인을 했었는데 뭔가 밀접하게 연결이 되어 있지 않다는 느낌이 강했습니다.
그래서 Tcp/IP 통신을 이용하여 상호 연동하는 방식으로 변경하기로 했습니다.
AutoCAD에 플러그인이 로딩됨과 동시에 Tcp/IP로 Host 어플리케이션이 접속하기를 기다립니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | public void DoAcceptTcpClient() { _TcpListener.Start(1); // Start to listen for connections from a client. while (true) { // Accept the connection. using (TcpClient client = _TcpListener.AcceptTcpClient()) { // Get a stream object for reading and writing using (NetworkStream stream = client.GetStream()) { DataSet dsParam = new DataSet(); #region get data size byte[] buffer = new byte[sizeof(long)]; stream.Read(buffer, 0, buffer.Length); Int64 iDataSize = BitConverter.ToInt64(buffer, 0); #endregion using ( var ms = new MemoryStream() ) { buffer = new byte[1024]; while (ms.Length < iDataSize) { int read = stream.Read(buffer, 0, 1024); ms.Write(buffer, 0, read); } ms.Position = 0; dsParam.ReadXml(ms); } /// Use controls' Invoke method bucase can't get document in thread DataSet res = new DataSet(); _ctrl.Invoke(new RequestDispatcher(DispatchRequest), new object[] { res,dsParam}); /// up to here if(null != res) { using ( var ms = new MemoryStream() ) { res.WriteXml(ms); byte[] oDataSize = BitConverter.GetBytes(ms.Length); buffer = new byte[oDataSize.Length + ms.Length]; System.Buffer.BlockCopy(oDataSize, 0, buffer, 0, oDataSize.Length); System.Buffer.BlockCopy(ms.GetBuffer(), 0, buffer, oDataSize.Length, (int)ms.Length); stream.Write(buffer, 0, buffer.Length); } stream.Flush(); } } } } } | cs |
데이타는 DataSet을 이용하여 서로 주고 받도록 하였습니다.
이렇게 플러그인이 로딩되고 난 뒤에,
Host 어플리케이션이 플러그인에 접속해서 데이타를 주고 받을 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | protected DataSet ExecuteCommand() { DataSet res = new DataSet(); try { using (TcpClient tcpClient = new TcpClient("127.0.0.1", PlugInServiceCommand._Port)) { using (NetworkStream stream = tcpClient.GetStream()) { DataSet dsParam = this.GetCommandParam(); if (null != dsParam) { #region send data using (var ms = new MemoryStream()) { dsParam.WriteXml(ms); byte[] oDataSize = BitConverter.GetBytes((Int64)(ms.Length)); byte[] buffer = new byte[oDataSize.Length + ms.Length]; System.Buffer.BlockCopy(oDataSize, 0, buffer, 0, oDataSize.Length); System.Buffer.BlockCopy(ms.GetBuffer(), 0, buffer, oDataSize.Length, (int)ms.Length); stream.Write(buffer, 0, buffer.Length); } stream.Flush(); #endregion #region get result from AutoCAD { byte[] buffer = new byte[sizeof(long)]; stream.Read(buffer, 0, buffer.Length); Int64 iDataSize = BitConverter.ToInt64(buffer, 0); buffer = new byte[iDataSize]; using (var ms = new MemoryStream()) { stream.Read(buffer, 0, (int)iDataSize); ms.Write(buffer, 0, buffer.Length); ms.Position = 0; res.ReadXml(ms); } } #endregion } } } } catch (System.Exception ex) { throw ex; } return res; } | cs |
댓글
댓글 쓰기