C++ 또는 C++/CLI 고수들에게 도움을 구합니다.

  • Post Author:
  • Post Category:
  • Post Comments:5 Comments
  • Post last modified:June 5, 2008

C++/CLI 코드를 작성하다가 괴상한, 아니 능력이 모자라서 이해 못하는 현상을 발견해서 이 블로그 구독자들의 도움을 받아볼까 합니다. 우선 다음 코드를 봐주세요.

inline MyString marshal_as(System::String^ const & _from_obj)
{
	if(_from_obj != nullptr)
	{

		cli::pin_ptr<const wchar_t> _pinned_ptr = PtrToStringChars(_from_obj);
		MyString _to_obj(static_cast<const wchar_t *>(_pinned_ptr), _from_obj->Length);

		return _to_obj;
	}
	else
	{
		throw gcnew System::ArgumentNullException(_EXCEPTION_NULLPTR);
	}
}

static CClassManaged^ FindClass(System::String^ className)
{
	// StaticFindClass의 CHECK에서 걸린다.
	const TCHAR* const classNameNative = marshal_as(className).c_str();

	// 작동한다
	// MyString ss = marshal_as(className);
	// const TCHAR* const classNameNative = ss.c_str();

	CClass* classObj = CClass::StaticFindClass(classNameNative);
	return gcnew CClassManaged(classObj);
}

CClass*	CClass::StaticFindClass(const TCHAR* const ClassName)
{
	std::map<MyString, CClass*>::const_iterator It = GClassMap.find(ClassName);
	CHECK(It != GClassMap.end());
	if (It == GClassMap.end()) return NULL;
	return It->second;
}


CClassManaged^ managedClass = CClassManaged::FindClass("DBObject_SessionInfo");

우선 사전지식부터 설명해보겠습니다. MyString 클래스는 사실상 std::wstring과 같습니다. 메모리 할당자만 바꾼 문자열 클래스입니다. marshal_as 는 <msclr/marshal_cppstd.h>에 구현된 코드와 동일한데, std::wstring이 MyString으로 바뀐 것만 다릅니다.

맨 아래 CClassManaged::FindClass 메서드를 호출하는 코드가 시작점입니다. 닷넷 문자열(System::String)을 받아서 C 문자열(TCHAR*)로 변환합니다. 이때 문자열 변환을 맡는 메서드가 marshal_as입니다. marshal_as는 MyString을 반환하는데, 이렇게 반환한 문자열을 다른 MyString 인스턴스에 할당한 다음, MyString::c_str()을 호출하면 괜찮습니다.

한데 명시적으로 할당하지 않고 곧장 MyString::c_str()을 호출하면 큰일이 납니다. std::map에서 문자열을 찾는 도중에(GClassMap.find), CHECK 조건에 걸려버립니다. 왜 그런가 했더니 GClassMap.find을 나오는 순간 ClassName 값이 Empty("")가 되어버렸기 때문입니다.

어째서 이런 일이 벌어지는 것일까요?

Kubernetes, DevSecOps, Golang, 지속적인 통합 등 다양한 주제에 관심이 많다.
follow me
  • 데이터가 과학이 아니라 환상에 불과할 때가 더 많다. 특히 그래프는 여러 변수를 종합하지 않고 하나의 메트릭을 단순하게 해석하는 경향을 강화하는 면이 있다. 지표를 볼 때 내가 뭘 빼먹었나 곱씹어보는 버릇을… https://t.co/IzhrDBR7bF
    1 day ago
  • 대체로 동의한다 https://t.co/55tzHF1jmV
    2 days ago
  • eBPF – Rethinking the Linux Kernel – Google Slides https://t.co/lx8ksB70WR
    2 days ago
Buy me a coffeeBuy me a coffee
×
Kubernetes, DevSecOps, Golang, 지속적인 통합 등 다양한 주제에 관심이 많다.
Latest Posts