'com'에 해당되는 글 2건

  1. 2008/01/23 comsupp.lib
  2. 2007/02/23 COM/ATL 기초(코드프로젝트)
sw2008/01/23 16:18
[출처]http://www.sysnet.pe.kr/Default.aspx?mode=2&sub=0&detail=1&wid=32 [[COM/COM+ 이야기] _bstr_t, CComBSTR, string 클래스 사용]


[내용]
저는 _bstr_t, CComBSTR 클래스와 STL 의 string 클래스를 주로 사용해서 "문자열 연산" 을 합니다.

한번 보시겠어요! ^^

HTML 스크립트에서 다음처럼 메소드를 부른다고 할때,
var szText = obj.DoWork( "TEST" );

다음과 같이 정의할 것입니다.
HRESULT DoWork( [in] BSTR szInText, [out,retval] BSTR *szOutText )
{
_bstr_t bstrText = szInText;
string strText = LPCSTR( bstrText );

*szOutText = _bstr_t( strText.c_str() ).copy();
return S_OK;
}

그런데, 이 때 주의할 점이 몇가지 있습니다.

1. _bstr_t::LPCSTR 연산자 사용 주의:
만약, 해당 _bstr_t 클래스가 보유하고 있는 텍스트의 length 가 0 인 경우에는, 오류가 발생합니다.

2. _bstr_t 클래스는 대용량 문자열을 감당할 수 없습니다. 제가 정확한 수치는 테스트를 안해봐서 잘 모르겠습니다. 아마도 _bstr_t 클래스에서 내부적으로 사용하는 _com_util::ConvertStringToBSTR 함수의 오류 같은데요.
MB 단위의 글자는 여지없이 다운되니 조심하셔야 됩니다. 그런 경우, _bstr_t 클래스는 사용하지 마시고, CComBSTR 클래스를 사용해야 됩니다. 대신에, CComBSTR 클래스 같은 경우는 LPCSTR() 연산자가 없으므로 ANSI 문자열로 변환할 경우에는 WideCharToMultiByte 함수를 사용해야 하는 불편함이 있습니다.

위의 2가지를 반영한 코드를 다시 보겠습니다.

HRESULT DoWork( [in] BSTR szInText, [out,retval] BSTR *szOutText )
{
_bstr_t bstrText = szInText;
if ( bstrText.length() == 0 ) return S_OK;

string strText = LPCSTR( bstrText );

// 만약 strText 에 대용량 문자열이 저장된 경우
CComBSTR suText = strText.c_str();
*szOutText = suText.Copy();
return S_OK;
}

최근에, VS.NET 에서 COM 개체를 만들 일이 좀 있었는데요.
VC++ 6.0 에서는 제가 그 동안 모아놓은 라이브러리를 습관적으로 Include 시켜서 알지 못했는 데, _bstr_t 와 관련해서 시행착오를 겪었습니다.
물론, 이 점은 VC++ 6.0 에서도 마찬가지입니다.

_bstr_t 클래스는 <comutil.h> 에 정의되어 있습니다.
그런데 그 안에서 예외에 대한 처리를 _com_error 에서 하는 데, 그 때문에, _bstr_t, _variant_t 클래스 등을 사용하기 위해서는
#include <comutil.h>
#pragma comment(lib, "comsupp.lib")
위와 같이 해주어야 합니다.

아시는 분은 아시겠지만, 위의 구문은
#include <comdef.h>
하나로 해결이 되어지죠.
Posted by redef
TAG com, 소스

댓글을 달아 주세요

sw2007/02/23 14:34
Introduction
이 글은 ATL을 사용하여 COM서버를 어떻게 만들것인지와 Visual C++ 와 Visual Basic 으로 부터 서버를 호출하는 방법을 알려 줄 것이다.

COM을 깊이 있고 자세하게 다루지 않을 것이며 IDL로 당신을 괴롭히고 싶지 않다. 이 문서는 새로운 VC++프로그래머에게 보여주기 위해 설계할것이다. 어떻게 간편하게 “Simple” COM 객체를 ATL로 만들 것인지 그리고 더 배우기 위해 갈망하는 그들을 위한 것이다.

Step 1: Running the ATL COM Wizard
첫번째로 해야 할일은 Visual C++을 실행하여 new project를 만드는 것이다.

“ATL COM AppWizard”를 선택한다.

프로젝트 이름을 “Simple_ATL”로 한다.

프로젝트를 저장할 곳을 정한후 OK버튼을 누른다.

몇가지 선택할 화면을 보게 될거다.

첫번째 선택은 “Server Type”이다.

Server DLL로 빌드를 할 것이므로 서버타입의 “Dynamic Link Library” 로 선택을 해야 한다.

다른 세개의 체크박스들은 지금 다루고 있는 프로젝트에서는 신경쓸 필요가 없으므로 그냥 넘어간다.

finish버튼을 눌러 위자드로 적당하게 잘 맞춰서 파일을 만든다.

“New Project Information” 윈도우가 나타나 어떤 파일들이 만들어질것인지 알려준다.

Ok 버튼을 누른다.

Step 2: Creating a new ATL object
VC++ IDE에서 “Workspace View”가 보일것이다.

“View” 메뉴를 클릭하여 “Workspace”를 선택할 수도 있다.

세개의 탭에서 “ClassView” 탭을 클릭한다.

“Simple_ATL Classes” 가 보일것이다.

마우스 오른쪽버튼을 클릭하여 팝업 메뉴에서 “New ATL Object”를 선택한다.

아래와 같은 윈도우를 볼수 있다.
사용자 삽입 이미지
















기본선택(Simple Object)가 우리가 원하는 것이다.

next버튼을 클릭하면 “ATL Object Wizard Properties” 윈도가 보인다.

“Short Name” 텍스트 박스에 “First_ATL”이라고 입력한다.

위자드가 자동적으로 나머지 택스트 박스를 채워준다.

탭에서 “Attributes”를 선택한다.

여기서 몇가지를 선택한다.

첫번째로 선택할 Threading Model은 기본설정인 Apartment Model을 선택한다.

“Interface”에서 “Dual”을 선택한다.

마지막으로 여기서 언급하지 않을 “Aggregation”을 “No”를 클릭한다.

아래쪽의 3개의 체크박스들에 대해서는 우리는 생각할 필요없다.

Ok버튼을 클릭하면 새로운 ATL Simple Object를 위자드가 만들것이다.
사용자 삽입 이미지

















Step 3: Adding a method
워크스페이스의 “ClassView”탭을 클릭해보면, 위자드가 추가해준 트리의 가지가 있다는것을 알것이다.

첫번째로 우리가 원하는 메쏘드를 추가 할 것이다.

“IFirst_ATL”위에서 마우스 오른쪽을 클릭하여 “Add Method”를 클릭하여 쉽게 만들수 있다.
사용자 삽입 이미지























“Add Method”를 클릭하면 “Add Method to Interface”윈도를 볼것이다.

기본적으로 메소드는 “HRESULT”를 리턴할수 있게 되어있는것을 볼수 있다.

대부분 이와 같이 놔둔다.

다음 텍스트박스에서 메소드이름을 정한다.

“AddNumbers”라고 할거다.

마지막 텍스트 박스에는 사용하기 원하는 파라미터들을 넣는다.

두개의 숫자를 더할것이고 결과를 돌려줄것이다 그래서 세개의 파라미터를 사용한다.

마지막 파라미터는 포인터일 것이다.

튜토리얼의 300페이지 IDL은 제외 한것이다 우리 필요한 형태로 파라미터 텍스트 박스를 아래와 같이 채운다.

[in] long Num1, [in] long Num2, [out] long *ReturnVal
아주간단하게,두개의 파라미터는 값이 들어오는 [in], 마지막 값은 요구의 반환값 [out]을 선언했다.

(이런것을 처음보는 사람은 이상하게 보일것이지만 COM책을 한두권 읽다 보면 이것은 더욱 직관적으로 보일것이다.)

Ok버튼을 클릭한다.

“ClassView”탭과 확장 표시인 “+” 를 클릭하여 트리를 완전히 다 열어본다.

가장위 인터페이스(”IFirst_ATL”)의 아래에서 “AddNumbers” 메소드와 파라미터들을 갖고 있는 것을 볼수 있다.

그 메소드를 더블 클릭하여 그곳에 코드를 입력한다.

코드는 아래와 같다.

STDMETHODIMP CFirst_ATL::AddNumbers(long Num1, long Num2, long *ReturnVal)
{
// TODO: Add your implementation code here
*ReturnVal = Num1 + Num2;
return S_OK;
}
Step 4: Compiling the DLL
믿거나 말거나지만 현재 작업이 ATL을 이용하여 COM서버를 만든것이다! 물론 컴파일 해야 한다.

“F7″ 버튼을 울러 VC++이 컴파일 하게 한다.

컴파일러가 만들어 내는데 몇초정도 걸린다.

컴파일러는 새로운 DLL을 다른 프로그램이 그것을 사용할수 있게끔 레지스트리에 등록해줄 것이다.

지금해보자.

Step 5: Testing the COM Server with Visual Basic
Visual Basic을 이용하여 COM Server를 테스해보자

(VB를 갖고 있지 않다면 그냥 넘어가서 VC++에서 COM Sever를 사용하는 테스트를 해보자)

VB를 실행하여 “Standard EXE”를 선택한다.

다이얼로그위에 버튼을 올려놓는다.

이제 COM Server 레퍼런스를 추가하자.

“Project”메뉴에서 “References”를 선택한다.

스크롤을 “Simple ATL 1.0 Type Library”가 보일때 까지 아래로 내려 선택한다.
사용자 삽입 이미지






















Ok 버튼을 클릭한다.

이제, 다이얼로그위에 올려 놓은 버튼을 더블클릭하면 VB는 버튼을 위한 코드를 입력할 위치로 갈것이다.

코드는 아래와 같다.

Private Sub Command1_Click()
Dim objTestATL As SIMPLE_ATLLib.First_ATL
Set objTestATL = New First_ATL
Dim lngReturnValue As Long objTestATL.AddNumbers 5, 7, lngReturnValue MsgBox “The value of 5 + 7 is: ” & lngReturnValue Set objTestATL = Nothing End Sub
VB프로그래머라면 위의 예제는 너무나 간단할 것이다.

객체를 선언하여 “AddNumbers”를 COM Server로 부터 호출할것이다 그리고 결과를 보여줄것이다.

“F5″키를 눌러 프로젝트를 실행한다음 버튼을 클릭해 보면 결과가 보여질 것이다.
사용자 삽입 이미지















너무나 쉽다.

VC++을 이용한 테스트를 다시해보자.

Step 6: Testing the COM Server with Visual C
Simple_ATL 프로젝트가 열려있다면 저장하고 닫고 새로운 프로젝트를 만든다.

“Win32 Console Application”을 선택하여 “Test_ATL”을 프로젝트 이름으로 한다.

Ok버튼을 클릭하고 다음 윈도우에서 기본설정(An empty project)를 선택한다.

finish버튼을 클릭하고 나서 ok버튼을 다시 누른다.

빈 프로젝트가 만들어 졌다.

Ctrl + N 키를 눌러 프로젝트에 파일을 추가한다.

윈도우에서 “C++ Source File”을 선택하여 “Test_ATL.cpp”를 파일명으로 한다.

Ok 버튼을 누른다.

빈 파일을 열렸을 것이다.

COM Server를 불러 테스트하기위한 코드를 약간 추가 한다.

새로운 cpp 파일에 아래와 같이 추가한다.

// You need to point this header file to the directory
// you placed the Simple_ATL project #include “..\Simple_ATL\Simple_ATL.h”
#include
// Copy the following from the Simple_ATL_i.c file
// from the Simple_ATL project directory
// NOTE: You can actually skip copying these if you want
// and just include the Simple_ATL_i.c file, I simply added
// it for clarity to show where these const variables are
// coming from and what they look like
const IID IID_IFirst_ATL = {0xC8F6E230,0x2672,0x11D3,{0xA8,0xA8,0x00,0x10,0x5A,0xA9,0x43,0xDF}};
const CLSID CLSID_First_ATL = {0x970599E0,0x2673,0x11D3, {0xA8,0xA8,0x00,0x10,0x5A,0xA9,0x43,0xDF}};
void main(void)
{
// Declare and HRESULT and a pointer to
// the Simple_ATL interface
HRESULT hr;
IFirst_ATL *IFirstATL = NULL;
// Now we will intilize COM
hr = CoInitialize(0);
// Use the SUCCEEDED macro and see if
// we can get a pointer
// to the interface
if(SUCCEEDED(hr))
{
hr = CoCreateInstance( CLSID_First_ATL, NULL, CLSCTX_INPROC_SERVER, IID_IFirst_ATL, (void**) &IFirstATL);
// If we succeeded then call the AddNumbers
// method, if it failed
// then display an appropriate message to the user.
if(SUCCEEDED(hr))
{
long ReturnValue;
IFirstATL->AddNumbers(5, 7, &ReturnValue);
cout < < "The answer for 5 + 7 is: " << ReturnValue << endl; IFirstATL->Release();
}
else
{
cout << “CoCreateInstance Failed.” << endl;
}
}
// Uninitialize COM
CoUninitialize();
}

Step 7: Compile and run the program
“F5″ 키를 눌러 컴파일 한다음 Ctrl + “F5″ 키를 눌러 실행한다.

도스 윈도우가 오픈되면서 결과가 보여질 것이다.


Posted by redef
TAG atl, com

댓글을 달아 주세요