728x90
반응형

Program Language/C & C++ 112

C4430 : missing type specifier - int assumed.

오래전에 해결해 두고 또 같은 에러로 헤매고 있었다니.. 아 놀라워라.. C++에서 순환 참조(?)하게 되면 이런 에러가 뜬다. //A.h #include "B.h" class A{ B* b; .. }; //B.h #include "A.h" class B{ A* a; // error error C4430: missing type specifier - int assumed. } 이런 식으로 말이다. 결국 전방 선언을 이용해서 해결해야 한다. //B.h class A; // change the include of A.h to forward declaration class B { A* a; }; 대신 소스파일에서 해당 헤드파일을 포함해주면 된다.

[C++] STL map에서 erase 사용 시 주의점

for (auto itr = m_elems.begin(); itr != m_elems.end(); ++itr) { if (itr->second->locking && !ignore_locked_obj) continue; m_elems.erase(itr); } map을 사용하여 조건을 통한 삭제를 실행하려 했는데, runtime error가 발생한다. 조건을 만족하는 iterator가 나타났을 때 해당 iterator를 지워버리면 해당 iterator는 end가 되어 버렸다. erase 하면 pos 값이 날아가버려서 그런가 보다. 미리 복사해 둬야 에러를 발생시키지 않는다. for (auto itr = m_elems.begin(); itr != m_elems.end();) { if (itr->second->..

/SAFESEH (이미지에는 안전한 예외 처리기가 있습니다.)

https://learn.microsoft.com/ko-kr/cpp/build/reference/safeseh-image-has-safe-exception-handlers?view=msvc-170 /SAFESEH(이미지에 안전한 예외 처리기 포함) 자세한 정보: /SAFESEH(이미지에 안전한 예외 처리기가 포함됨) learn.microsoft.com 오늘은 컴파일을 시도하려는데 처음 보는 에러가 발생했다. 분명 예전에는 발생하지 않았는데, VS 버전이 바뀌어서 그런 것 같기도 하다. 해당 페이지에서는 속성/링커/고급에서 안전환 예외 처리 속성을 변경하라고 되어 있다. 하라는 대로 하니 컴파일이 정상 진행되었다. x86 대상에 연결할 때만 유효하다고 하는데, 자세한 것은 잘 모르겠다.

[C++] List 에서 pair로 된 데이터 찾기

list를 사용하다가 두 개의 데이터를 담아야 해서 pair를 사용했다. 찾을 때는 통상 first로 찾았는데, 이는 사실 map을 이용하는 편이 훨씬 편하다. list에서 pair를 사용하여 둘 다 만족하는 데이터를 검색하는 약간의 뻘짓을 해보았다. #include #include #include #include using namespace std; int main() { list list1; list1.emplace_back("1", "1"); list1.emplace_back("2", "1"); list1.emplace_back("2", "3"); string row = "2"; string col = "1"; auto func = [row,col](pair const & b) { return b...

[C++] C#에서 사용할 수 있게 Lib 만들기

C#에서 사용 가능한 C++ 라이브러리를 만들려면 우선 CLR을 사용할 수밖에 없다. 우선은 Win32 Lib를 생성해야 한다. C#에서 사용할 수 있는 것은 Explicit Link임으로 extern "C" __declspec(dllexport)를 이용한 선언을 해줘야 한다. extern "C" __declspec(dllexport) int add_integer(int a, int b) { return a + b; } 이제, C# 콘솔 프로젝트를 만든다. C++프로젝트와 C# 프로젝트는 출력 폴더가 다르기 때문에, 테스트하려면 생성된 dll 파일을 옮겨줘야 한다. 우선 번거롭지 않기 위해서 C++ 출력을 C# bin 폴더로 지정했다. C#에서 외부 라이브러리를 가져오기 위해서 using System.R..

[C++] C#에서 사용할 수 있게 Lib 만들기 (CLR Class)

C#에서 C++을 만들려면 결국 둘 사이에 공통되는 부분을 이용해서 전달해야 하는 듯하다. CLR 클래스 라이브러리를 사용하면 조금 편하게 C#에서 사용할 수 있다. CLR 항목을 선택한 뒤 Class Library를 선택하면 만들 수 있다. 간단하게 더하기 함수를 만든다. namespace CLRClassLib { public ref class Calculator { public: int add(int a, int b) { return a + b; } }; } 그리고 테스트를 할 수 있도록 C# 콘솔 프로젝트를 만든다. Reference에서 추가를 눌러, 만들어 놓은 CLR 프로젝트를 등록하자. Reference에서 CLRClassLib이 추가되었다. using CLRClassLib을 작성한 뒤, CL..

[C++] 소문자/대문자 변환 (tolower, toupper)

파일을 열 때 확장자 구분을 하려고 하니 대문자, 소문자에 모두 대응해야 해서 모두 소문자로 바꾼 상태에서 비교하기 위해서 사용하였다. std::wstring strExtension = strPath.substr(strPath.size() - 3, 3); for (int i = 0; i < strExtension.size(); i++) strExtension[i] = tolower(strExtension[i]); bool bSucs = false; // 확장자가 JPEG가 아니라면 진행하지 않는다. if (strExtension == L"jpg" || strExtension == L"jpeg") { .... 예제는 소문자로 변환하는 예제이며 대문자로 변환하려면 아래와 같이 하면 된다. for (int i..

[C++] wifstream/wofstream 한글 인식 문제

ifstream과 ofstream의 경우에는 한글을 읽어오는데, wide char의 경우에만 한글 인식이 안되었다. 그래서 검색해보니 로컬 지정을 해야 한다고 한다. 아마 unicode로 저장하지 않아서 인 것 같기도 하다. 그래서 지정하고 실행해보니 잘된다. wofstream wofs; wofs.imbue(std::locale("kor")); wofs.open(_filepath); _tsetlocale(LC_ALL, _T("Korean")); 이 녀석을 추가해줘야 하는데, ANSI에서만 제대로 동작한다. UTF-8로 저장하면 또 못 읽어온다. 그냥 Unicode로 작업할까 싶기도 하지만, 우선 급해서 이렇게 해결한다.

[C++] unary_function, binary_function

unary_function은 하나의 인수로 함수 객체를 작성하기 위한 기본 클래스다. binary_function은 두 개의 인수로 함수 객체를 작성하기 위한 기본 클래스다. operator() 정의하지 않기 때문에 파생 클래스가 이를 정의해야 한다. class name_equal1 : public unary_function { string name_; public: name_equal1(const string name) : name_(name) {} bool operator()(const string& var) const { return name_ == var; } }; class name_equal2 : public binary_function { public: bool operator()(const..

[C++] string 공백 문자 제거

string에서 특정 문자를 제거하려면 erase 함수를 사용해야 한다. 좌측 문자열을 제거하기 위해서는 erase ( 시작 위치, 개수)를 사용하고, 우측 문자열을 제거하기 위해서는 rease (크기)를 사용한다. text.erase(0, npos); text.erase(npos); 특정 문자를 제거하기 위해서는 해당 문자가 아닌 위치를 우선 찾아야 한다. 이때 좌측부터 찾을 때에는 find_first_not_of를 우측부터 찾을 때에는 find_last_not_of를 사용한다. npos = text.find_first_not_of(' '); npos = text.find_last_not_of(' '); 두 함수를 이용하여 좌측, 우측 공백 문자를 제거해보자. string text(" shared pt..

[C++] shared_ptr의 잘못된 사용

smart_ptr를 익히고 나서 꾸준히 unique_ptr와 shared_ptr를 사용하였다. 그 후 프로그램을 종료할 때마다 메모리 액세스 에러가 자주 일어났다. 자동으로 메모리를 해제해 준다고 하여 스마트 포인트를 사용하였는데 오히려 문제가 더 생겼다. shared_ptr의 경우 소멸될 때 아무도 사용하고 있지 않다면 메모리를 자동으로 해제해 준다. 하지만 참조자로 받아서 shared_ptr로 변경해서 사용한다면 메모리를 두 번 해제하는 경우가 발생한다. #include #include #include using namespace std; void printf(string* ptext) { shared_ptr shrd_text(ptext); cout c_str()

[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

728x90
반응형