블로그 이미지
fiadot_old

칼퇴근을 위한 게임 서버 개발 방법론에 대한 심도있는 고찰 및 성찰을 위한 블로그!

Rss feed Tistory
Technical Article 2007. 9. 26. 21:21

wchar_t 타입을 받는 형식라이브러리 빌드 문제 C2664 Part 2

MIDL의 파싱 오류라고만 치부하기에는 MSDN의 샘플코드도 문제가 있었다.

이전글에서

 HRESULT hr = m_pSpMgr->S_AddUser( (unsigned short*)("first112"), 0, (unsigned short*)("what"), (unsigned short*)("whatu"));


이런 코드를 사용했는데 TCHAR* 를 이용해서 인자를 전달하지 않고 위에 처럼

문자열 상수를 사용하게 되면 유니코드로 들어가는게 아니라,

일반 ansi char로 인자가 전달되게 된다.

사용자 삽입 이미지
( 이 이미지는 what에 해당하는 부분이 아예 제대로 값이 전달 안되었는데 실제로는 what 0x00 4개가 전달된다 )

제대로 전달하기 위해서 코드는 다음과 같이 해야하며,

 HRESULT hr = m_pSpMgr->S_AddUser( (unsigned short*)_T("first112"), 0, (unsigned short*)_T("what"), (unsigned short*)_T("whatu"));



좀더 C++ 스럽게 표현하면

  HRESULT hr = m_pSpMgr->S_AddUser(reinterpret_cast<unsigned short*>(L"first112"),
           0,
           reinterpret_cast<unsigned short*>(L"what"),
           reinterpret_cast<unsigned short*>(L"whatu"));


이와 같이 해야 맞을것이다.

,
Technical Article 2007. 9. 26. 20:51

wchar_t 타입을 받는 형식라이브러리 빌드 문제 C2664

#include "stdafx.h"
#import "progid:BWDBAgent.SPMgr.1" no_namespace named_guids

int _tmain(int argc, _TCHAR* argv[])
{
 ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
 {
  ISPMgrPtr m_pSpMgr;

  m_pSpMgr = ISPMgrPtr(__uuidof(CSPMgr));

  HRESULT hr = m_pSpMgr->S_AddUser(_T("first1"), 0, _T("what"), _T("whatu"));

 }
 ::CoUninitialize();
 return 0;
}

위와 같은 간단한 코드를 빌드하는데

..\bwdbagenttester\bwdbagenttester.cpp(15) : error C2664: 'ISPMgr::S_AddUser' : 매개 변수 1을(를) 'const wchar_t [7]'에서 'unsigned short *'(으)로 변환할 수 없습니다.
1>        가리킨 형식이 관련이 없습니다. 변환하려면 reinterpret_cast, C 스타일 캐스트 또는 함수 스타일 캐스트가 필요합니다.

이런 에러가 발생하였다.


COM 인터페이스는 다음과 같다.

__interface ISPMgr : IUnknown
{
 [helpstring("메서드 S_AddUser")] HRESULT S_AddUser([in] wchar_t* userid, [in] LONG usertype, [in] wchar_t* password, [in] wchar_t* nick);
};

저번에도 봤었는데 가물가물해서 정리해놓는다.


MSDN에 보면

midl 컴파일러에 있는 버그로 인해 wchar_t 형식이 형식 라이브러리에서 부호 없는 short로 생성됩니다. 이 오류를 해결하려면 C++ 소스 코드에서 형식을 캐스팅하거나 idl 파일에서 형식을 문자열로 정의해야 합니다.




  HRESULT hr = m_pSpMgr->S_AddUser((unsigned short*)("first1"), 0, (unsigned short*)("what"), (unsigned short*)("whatu"));

이렇게 하면 된다.

되도록이면, BSTR을 사용하는게 나을듯 싶다.

최대한 고치지 않고 부분만 빼낼려고 했더니원 -_-;;

,
Technical Article 2007. 7. 9. 11:53

NateON dispatch Interface를 통한 친구상태 체크하기

#import "progid:NateOn.NateMessengerApi.1" no_namespace
void CAutoTestDlg::OnBnClickedButton1()
{
 // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

//  uuid(A02AC169-B150-43DE-8BD4-109B9DE6B34B),
//
//  INateOnApiAtx
//
//  dispinterface INateMessengerApi
//
//  [id(0x0000000c), helpstring("method GetMyId")]
//  BSTR GetMyId();
 
 INateMessengerApiPtr m_pNate;

 m_pNate = INateMessengerApiPtr(__uuidof(NateMessengerApi));

 BSTR pID = m_pNate->GetMyId();

 TCHAR szFinal[255];
 // direct conversion from BSTR to LPCTSTR only works
 // in Unicode
 _stprintf(szFinal, _T("%s"), (LPCTSTR)pID);
 AfxMessageBox(szFinal);

 CString str;

VARIANT_BOOL bOnline = m_pNate->IsBuddyOnline("dlsdoㅌㅌㅌ@nate.com");
 if ( VARIANT_TRUE  == bOnline )
  str.Format(L"true");
 else
  str.Format(L"false");

 AfxMessageBox(str);


COM 공부하다가 뻘짓 -_-;;;

OLE View로 타입라이브러리 보다가 '참 많은 놈들이 COM으로 짰구나' 생각하다

아니 네이트~~ 이러면서 그냥 테스트 해본거..

물론 ATL은 필수!
,
TOTAL TODAY