일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- docker
- c언어
- Houdini
- gitlab
- 포인터
- jupyter lab
- git
- Flutter
- Data Structure
- 구조체
- jupyter
- Python
- 깃
- 도커
- Algorithm
- dart 언어
- C언어 포인터
- c# 추상 클래스
- 유니티
- c#
- 다트 언어
- C# delegate
- C++
- Unity
- vim
- c# winform
- 플러터
- c# 윈폼
- github
- HTML
- Today
- Total
nomad-programmer
[Programming/C#] COM (Component Object Model) 본문
COM 이란?
COM은 Component Object Model의 약자로, 마이크로소프트의 소프트웨어 컴포넌트 규격을 말한다. OLE, ActiveX, COM+와 같은 파생 규격들이 모두 COM을 바탕으로 만들어졌다.
마이크로소프트에서 출시되는 대부분의 제품이 COM을 지원한다.
COM은 부품 역할을 하는 소프트웨어이다. COM 컴포넌트는 그래픽 프로그래밍에 서툰 프로그래머가 화려한 차트 기능을 어플리케이션에 넣을 수 있도록 해주고, 엑셀 문서의 파일 구조를 몰라도 엑셀 문서를 읽거나 쓸 수 있도록 해준다.
C#을 비롯한 .NET 언어들은 RCW(Runtime Callable Wrapper)를 통해 COM 컴포넌트를 사용할 수 있다.
RCW는 .NET 프로엠워크가 제공하는 Type Library Importer(tlbimp.exe)를 이용해서 만들 수 있는데, 비주얼 스튜디오를 이용해서 COM 객체를 프로젝트 참조에 추가하면 IDE가 자동으로 tlbimp.exe를 호출하여 RCW를 만들어준다.
RCW는 COM에 대한 proxy 역할을 함으로써 C#코드에서 .NET 클래스 라이브를 사용하듯 COM API를 사용할 수 있게 해준다.
C#과 COM
C# 4.0 이전에는 COM 친화적인 언어였던 비주얼 베이직은 COM과 잘 어울렸지만, C#은 RCW가 있어도 여전히 COM과 친화적이지 않았다. 그 원인은 다음의 두가지이다.
- COM은 메소드가 결과를 반환할 때 실제 형식이 아닌 object 형식으로 반환한다. 이 때문에 C# 코드에서는 이 결과를 실제 형식으로 변환을 해줘야 하는 번거로움이 있었다.
- COM은 오버로딩을 지원하지 않는다. 대신 메소드의 선택적 매개 변수와 기본값 매개 변수를 지원한다. C#은 4.0 버전으로 업그레이드되기 전까지는 선택적 매개 변수와 기본값 매개 변수를 지원하지 못했다. 이 때문에 C# 코드에서 COM API 하나를 호출하려면 사용하지도 않을 매개 변수를 수없이 입력해줘야 하는 번거로움이 있었다.
C# 4.0 버전에 이르러서야 dynamic 형식의 도임을 통해 1번 문제를 해결하고, 메소드의 선택적 매개 변수와 기본값 매개 변수 도입을 통해 2번 문제를 해소했다. 비로소 C#도 VB처럼 COM 친화적인 언어가 된 것이다.
마이크로소프트는 워드를 비롯해 파워포인트, 엑셀 등 오피스 제품들의 기능을 코드에서 이용할 수 있도록 이 소프트웨어들을 COM 컴포넌트로 구성해 놓았다.
// C# 3.0 이하
public static void OldWay(string[,] data, string savePath)
{
Excel.Application excelApp = new Excel.Application();
excelApp.Workbooks.Add(Type.Missing);
Excel.Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet;
for(int i=0; i< data.GetLength(0); i++)
{
((Excel.Range)workSheet.Cells[i + 1, 1]).Value2 = data[i, 0];
((Excel.Range)workSheet.Cells[i + 1, 2]).Value2 = data[i, 1];
}
workSheet.SaveAs(
savePath + "\\test-book_old.xlsx",
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing);
excelApp.Quit();
}
// C# 4.0 이상
public static void NewWay(string[,] data, string savePath)
{
Excel.Application excelApp = new Excel.Application();
excelApp.Workbooks.Add();
Excel._Worksheet workSheet = excelApp.ActiveSheet;
for(int i=0; i<data.GetLength(0); i++)
{
workSheet.Cells[1 + 1, 1] = data[i, 0];
workSheet.Cells[1 + 1, 2] = data[i, 1];
}
workSheet.SaveAs(savePath + "\\test-book-dynamic.xlsx");
excelApp.Quit();
}
C# 4.0 버전 이후로 수많은 형식 변환과 의미 없는 매개 변수 입력이 사라졌다. 선택적 매개 변수와 dynamic 형식은 비주얼 스튜디오가 RCW를 만들 때 사용했다.
Excel COM 사용 예제
1. 비주얼 스튜디오에서 새 프로젝트를 생성합니다. "콘솔 앱 (.NET Framework)" 템플릿 선택. 프로젝트 이름은 알아서 정하면 된다.
2. 솔루션 탐색기에서 Program.cs 파일의 이름을 원하는 이름으로 변경한다.
3. 솔루션 탐색기에서 "References (참조)" 항목 위에 마우스 오른쪽 버튼을 클릭하여 [Add Reference... (참조 추가)] 항목을 선택한다.
4. 아래와 같은 창이 나타나면, 창의 왼편에서 [COM] -> [Type Libraries] 항목을 선택한다. 그리고 구성 요소 목록에서 "Microsoft Excel 16.0 Object Library" 를 선택한 후 <확인> 버튼을 클릭한다.
5. 작업이 성공적으로 진행되었다면 아래와 같이 References 항목에 Microsoft.Office.Core 어셈블리와 Microsoft.Office.Interop.Excel 어셈블리가 추가된 것을 확인할 수 있다.
Excel에 데이터를 입력한 후 저장하는 예제
using System;
using Excel = Microsoft.Office.Interop.Excel;
namespace COMInterop
{
class MainApp
{
public static void OldWay(string[,] data, string savePath)
{
Excel.Application excelApp = new Excel.Application();
excelApp.Workbooks.Add(Type.Missing);
Excel.Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet;
for(int i=0; i<data.GetLength(0); i++)
{
((Excel.Range)workSheet.Cells[i + 1, 1]).Value2 = data[i, 0];
((Excel.Range)workSheet.Cells[i + 1, 2]).Value2 = data[i, 1];
}
workSheet.SaveAs(
savePath + "\\test-book-old.xlsx",
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing);
excelApp.Quit();
}
public static void NewWay(string[,] data, string savePath)
{
Excel.Application excelApp = new Excel.Application();
excelApp.Workbooks.Add();
Excel._Worksheet workSheet = excelApp.ActiveSheet;
for(int i=0; i<data.GetLength(0); i++)
{
workSheet.Cells[i + 1, 1] = data[i, 0];
workSheet.Cells[i + 1, 2] = data[i, 1];
}
workSheet.SaveAs(savePath + "\\test-book-dynamic.xlsx");
excelApp.Quit();
}
static void Main(string[] args)
{
string savePath = System.IO.Directory.GetCurrentDirectory();
string[,] array = new string[,]
{
{"자료구조와 알고리즘", "2020" },
{"윈도우즈 프로그래밍", "2020" },
{"리눅스 프로그래밍", "2020" },
{"네트워크 프로그래밍", "2020" },
{"동시성 프로그래밍", "2020" }
};
Console.WriteLine("creating excel document in old way...");
OldWay(array, savePath);
Console.WriteLine("creating excel document in new way...");
NewWay(array, savePath);
}
}
}
/* 결과
creating excel document in old way...
creating excel document in new way...
프로그램을 실행한 폴더를 보면
test-old.xlsx, test-new-dynamic.xlsx 파일이 생긴것을 확인할 수 있다.
*/
'Programming > C#' 카테고리의 다른 글
[Programming/C#] 파일과 디렉토리 (0) | 2020.09.27 |
---|---|
[Programming/C#] 동적 언어와의 상호 운용성을 위한 dynamic 형식 (1) | 2020.09.27 |
[Programming/C#] dynamic 형식 (0) | 2020.09.26 |
[Programming/C#] 어트리뷰트 (Attribute) (0) | 2020.09.26 |
[Programming/C#] 리플렉션 (Reflection) (0) | 2020.09.25 |