728x90
반응형

C++ 161

[C++] 디버깅 모드 종료 시 메시지

프로그램을 종료하다 보면 다음과 같은 메시지를 만나게 된다. The program '[1528] ????????.exe' has exited with code 2 (0x2). 메모리 릭으로 골머리를 앓다보면 해당 메시지를 만나는 것만으로도 화들짝 놀라게 된다. 자라 보고 놀란 가슴 솥뚜껑보고 날라는 심정이랄까. 분명 메모리 릭을 가리키는 메시지도 있다. 정리를 해둘 필요는 있을 것 같다. The thread ??? has exited with code 0 (0x0) : Dialog IDOK, IDCANCEL을 이용하여 정상적으로 종료한 경우 The program '???.exe' has exited with code 2 (0x2) : Dialog 의 X 버튼을 사용하여 종료한 경우 The program ..

[C++] Dll Unloading 시 Kernel32.dll 에러

Dll을 LoadLibrary 이후, 프로그램을 닫을 때 Kernel32.dll 쪽에 access violation error 가 발생한다. 특정 Dll은 발생하고 또 특정 Dll은 발생하지 않는다. App - implicit Link - Explicit Link로 구성했는데, 프로그램 종료를 진행하면 App Closing 보다 Dll이 먼저 닫혀 버리는 것 같다. 소멸자의 FreeLibrary를 주석 처리하니 제대로 동작한다. 그리고 찾아보니 dll은 스스로 unloading 할 수 있는 방법이 없다는 것이다. FreeLibrary를 사용하면 래퍼런스 카운트가 0이 되어 FreeLibrary는 성공하지만 리턴하는 영역이 이미 해제된 영역이라 crash가 발생하게 된다는 것이다. 몇 시간 헤매고 또 하나..

[C++] 자료형 타입 확인하기

C++의 자료형을 확인할 필요가 있을 때가 있다. 템플릿을 이용하여 특정 자료형에 따라 다른 작업을 할 때도 사용할 수 있다. 굳이 알지 않더라도 많은 작업들을 해낼 수 있지만 가끔씩 생기는 답답함에 테스트를 해서 정리를 해 두었다. C++ STL에서 제공하는 typeid()를 사용하면 쉽게 알아낼 수 있다. #include "stdafx.h" #include #include using namespace std; int main() { void* v; int i; long l; double d; float f; cout

[C++] GetProcAddress가 nullptr을 Return 할 때,

기존에는 아무 생각 없이 잘 되었기 때문에 신경 쓰지 않았는데, 오늘 테스트 중에 계속 nullptr가 리턴되어서 난감했다. DLL에는 아래와 같이 만들어 주고 extern "C" __declspec(dllexport) int __get_string(string* str); extern "C" __declspec(dllexport) int __disp_string(); Main에는 아래와 같이 해 두었다. int main() { HMODULE hmodule = LoadLibrary(L"DllCommon.dll"); if (hmodule != NULL) { using FUNC_DISP = int(*)(); FUNC_DISP func = (FUNC_DISP)GetProcAddress(hmodule, "__d..

[C++] template를 이용하여 Bind 사용하기

bind를 사용하면 함수의 매개변수를 미리 지정하여 사용할 수 있다. 여기서 한 가지 주의할 점은 바인드로 보내는 참조자(&)는 값을 다시 가져오지 못하였다. 그래서 포인트로 강제하니 값을 얻어 올 수 있었다. int test_func(int in, shared_ptr out) { *out = in + 100; return *out; } int main() { shared_ptr out(new int); // 바인드 사용하기 auto f(bind(test_func, 10, out)); f(); cout

[C++] 마우스 이벤트 후킹

Windows에서 후킹을 하기 위해서 제공하는 함수들이 있다. 이것들은 모두 DLL 환경에서 제작되어야 한다. 후킹을 위한 DLL 프로젝트와 테스트를 위한 MFC 프로젝트가 필요하다. DLL 프로젝트 일전에는 후킹을 위한 함수를 만들 때에 모두 전역 변수와 전역 함수를 사용하였지만 관리하기가 쉽지 않았다. 검색하다 보니 싱글톤 클래스 형식으로 정리된 자료가 있어서 해당 방식으로 구현했다. 전역으로 작업하는 것이 간단하기는 하나 클래스 형식으로 하는 것이 관리가 더 편하다. case DLL_PROCESS_ATTACH: if (hook_mouse_callback::instance()->attach(hModule)) cout

코드/C++ 2022.05.11

[C++] Queue Clear

std::queue의 경우 clear를 제공해주지 않는다. 결국 size만큼 pop 해서 들어내야 한다. while(!q.empty()) q.pop(); 다른 방법으로는 빈 queue와 바꿔치기를 하면된다. queue empty; swap(q, empty); swap을 사용하려면 algorithm을 include 해야 한다. 그리고 새로운 방법으로 queue를 재선언해도 된다. q = queue(); How do I clear the std::queue efficiently? I am using std::queue for implementing JobQueue class. ( Basically this class process each job in FIFO manner). In one scenario, ..

[C++] condition_variable에서 unique_lock

thread 사이에 동기화를 할 때 lock을 잡는 것으로 가장 많이 사용되는 것은 lock_guard다. 소멸과 동시에 unlock을 해주기 때문에 자동으로 lock을 해제할 수 있기 때문이다. 편하지만 lock_guard는 오직 생성자, 소멸자를 통해서만 lock을 다룰 수 있다. unique_lock은 lock_guard에 몇 가지 추가적인 기능이 있다. lock을 획득하는 시점을 미룰 수 있고 lock을 잡기 위해 무한 대기하지 않아도 된다. lock을 획득하는 순서를 보장해주기도 한다. unlock 함수도 호출할 수 있다. coditional_variable은 조건을 만족하지 않으면 무한 대기하지 않고 thread를 바로 block 한다. thread가 block 되면 다른 thread로 넘어가..

싱글턴 패턴(Singleton Pattern)

싱글턴 패턴은 해당 클래스의 인스턴스가 하나만 만들어지고, 어디서든지 그 인스턴스에 접근할 수 있도록 하기 위한 패턴이다. 싱글턴 패턴은 클래스에서 자신의 단 하나뿐인 인스턴스를 관리하도록 만들면 된다. 그리고 다른 어떤 클래스에서도 자신의 인스턴스를 추가로 만들지 못하도록 해야 한다. 인스턴스가 필요하면 반드시 클래스 자신을 거치하도록 해야 한다. 그리고 어디서든 그 인스턴스에 접근할 수 있도록 만들어야 한다. 다른 객체에서 이 인스턴스가 필요하면 언제든지 클래스한테 요청을 할 수 있게 만들고, 요청이 들어오면 그 하나뿐인 인스턴스를 건네주도록 만들어야 한다. class Singleton { public: Singleton() = default; virtual ~Singleton() {} static ..

[ATL/MFC] 32Bit Software를 64Bit Software에서 사용하기

C++에서 x86, x64 프로그램은 서로 호환해서 사용할 수 없어서 별도로 만들어 사용해야 한다. 모든 프로그램을 자신 혹은 팀이 만들어 나간다면 아무런 문제가 없다. 하지만 외부로부터 제공되는 라이브러리나 개발이 종료된 라이브러리의 경우 32bit만 존재하는 경우가 종종 있다. 이럴 경우 두 프로그램의 통신을 이용하여 사용할 수 있다. 32bit 프로그램을 ATL로 둘러싸서 서버를 만든 후 64Bit 프로그램에서 해당 서버와 통신을 하게 된다. 서버 만들기 (ATL Project) Visual Studio에서는 ATL을 이용하여 서버 프로그램을 간단히 만들 수 있다. C++ 프로젝트에서 ATL/ATL Project를 선택한 뒤, Service(EXE)를 선택한 후 프로젝트를 생성한다. ServerX8..

[C++] unique_ptr<T> nullptr 비교하기

unique_ptr 는 객체를 비교하거나 nullptr를 비교하는 연산자를 제공해 준다. 이 사실을 알지 못했을 때에는 get()을 사용하여 확인했다. std::unique_ptr str; if (str.get() == nullptr) return; 하지만 unique_ptr 는 bool 타입으로 암시적으로 변화될 수 있다. unque_ptr이 nullptr이면 변환 결과는 false가 되고, 그렇지 않으면 true가 된다. 이를 이용하면 unique_ptr객체의 nullptr 체크를 할 수 있다. std::unique_ptr str; if (str) return; 두 unique_ptr 객체를 비교할 때에는. get() 멤버를 호출해서 비교해야 한다. 이 동작은 shared_ptr에도 마찬가지로 동작한다.

팩토리 패턴(Factory Pattern)

간단한 팩토리(Simple Factory)는 디자인 패턴이라고 할 수는 없다. 프로그래밍을 하는 데 있어서 자주 쓰이는 관용구에 가깝다고 할 수 있다. 단지 워낙 자주 쓰이기 때문에 패턴이라고 표현하기도 한다. 모든 팩토리 패턴에서는 객체 생성을 캡슐화한다. 팩토리 메서드 패턴(Factory Method Pattern)에서는 서브클래스에서 어떤 클래스를 만들지를 결정하게 함으로써 객체 생성을 캡슐화한다. 팩토리 메서드 패턴에서는 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 만든다. 팩토리 메서드 패턴을 이용하면 클래스의 인스턴스를 만드는 일을 서브클래스에 맡기는 것이다. 위의 클래스 다이어그램을 보면, Creator 추상 클래스에서 객체를 만들기..

데코레이터 패턴(Decorator Pattern)

OCP(Open-Closed Principle) 기존 코드는 건드리지 않은 채로 확장을 통해서 새로운 행동을 간단하게 추가할 수 있도록 한다. 이것을 달성하면 새로운 기능을 추가하는 데 있어서 매우 유연해서 급변하는 주변 환경에 잘 적응할 수 있으면서도 강하고 튼튼한 디자인을 만들 수 있다. 코드에서 확장해야 할 부분을 선택할 때는 세심한 주의를 기울여야 한다. 무조건 OCP를 적용하는 것은 시간 낭비가 될 수도 있고, 괜히 쓸 데 없는 일을 하는 것일 수도 있다. 결과적으로 불필요하게 복잡하고 이해하기 힘든 코드만 만들게 되는 부작용이 있을 수도 있으니 주의해야 한다. 데코레이터 패턴(Decorator Pattern)에서는 객체에 추가적인 요건을 동적으로 첨가한다. 데코레이터는 서브클래스를 만드는 것을..

옵저버 패턴(Observer Pattern)

옵저버 패턴(Observer Pattern)에서는 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의한다. 일대다 관계는 주제와 옵저버에 의해 정의된다. 옵저버는 주제에 의존한다. 주제의 상태가 바뀌면 옵저버한테 연락이 간다. 연락 방법에 따라 옵저버에 있는 값이 새로운 값으로 갱신될 수도 있다. 옵저버 패턴을 구현하는 방법에는 여러 가지가 있지만, 대부분 주체(Subject) 인터페이스와 옵저버(Observer) 인터페이스가 들어있는 클래스 디자인을 바탕으로 한다. 느슨한 결합(Loose Coupling)의 위력 두 객체가 느슨하게 결합되어 있다는 것은, 그 둘이 상호작용을 하긴 하지만 서로에 대해 서로..

728x90
반응형