728x90
반응형

C++ 161

error C3861: 'min': identifier not found

1>c:\program files (x86)\windows kits\8.1\include\um\gdiplustypes.h(689): error C3861: 'min': identifier not found 1>c:\program files (x86)\windows kits\8.1\include\um\gdiplustypes.h(690): error C3861: 'min': identifier not found 오랜만에 봐서 살짝 당황했네. MIN, MAX가 중복 선언돼서 문제 되는 건 기억나는데.. 이건 opencv와 Gdiplus의 min, max가 충돌(?) 혹은 선점이 잘못되어서 그런 것 같다. 를 사용하지 않았는데, 이런 에러가 떠다니, opencv.hpp 보다 먼저 인클루드 해주면 된다. #inc..

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->..

[C#] OCX에 포인터 데이터 넘기기

C#에는 기본적으로 포인터를 지원하지 않는다. 포인터를 사용하기 위해서 unsafe를 이용하던데, 기본적으로 사용하지 말라고 한 것을 굳이 사용해야 싶어서 구글링 해서 여기저기 검색해 보았다. 가장 간단한 방법으로 C++에서도 사용하던 것인데 포인터의 주소를 넘기는 것이다. 포인터의 주소는 32bit에서는 long으로 64bit에서는 __int64 혹은 long long으로 넘겨주곤 했다. C#은 모두 long long이다. 그렇기 때문에 OCX의 메서드를 만들 때에도 LONGLONG으로 만들어야 한다. void CtopgraphCtrl::AddArrayDataPtr(LPCTSTR name, LONG length, LONGLONG xPtr, LONGLONG yPtr, LONGLONG zPtr) 포인터의 ..

Program Language/C# 2022.10.26

[C#] C++로 만들어진 OCX 사용하기

C++로 ActiveX를 만든 뒤, 메서드나 속성을 등록하면 아래와 같은 형식이 된다. // Primary dispatch interface for CtopgraphCtrl [ uuid(E46EECAA-BACD-41EC-A75F-0D463AABA133) ] dispinterface _Dtopgraph { properties: [id(1000)] DOUBLE ScaleX; methods: [id(DISPID_ABOUTBOX)] void AboutBox(); [id(1)] void CreateGraph(BSTR name, LONGLONG color); [id(2)] void DeleteGraph(BSTR name); [id(3)] void Clear(); [id(4)] void AddData(BSTR nam..

Program Language/C# 2022.10.26

/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..

[OpenGL] GLAD 설치하기

https://glad.dav1d.de/ Extensions... glad.dav1d.de Glad 받기 버전이 많았지만 3.3으로 받았음. Language는 C/C++ , Profile은 Core으로 선택. Extensions는 뭔가 했는데 선택해주지 않아도 됨. Generate를 누르면 아래와 같은 파일이 생성됨. glad.zip만 다운로드하면 된다. 압축을 해제하면 해당 파일 모두 생성된다. zip 파일을 풀어서 자신의 include 폴더로 옮기면 된다. 그리고 경로를 추가해 준다. glad.c 파일을 프로젝트에 추가한다. 에러 C1853이 발생되는데, 여기서 멘붕이 살짝 올 수 있지만, 설정을 변경해 준다. 컴파일 후, 실행하면 정상 동작한다.

[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..

libjpeg 사용하기

jpeg format을 손 코드로 해보려다가 포기. 그냥 잘 만들어진 open source를 써야겠다는 생각이 들었다. 그중에서 가장 많이 쓰이는 것으로 보이는 libjpeg를 사용하기로 했다. libjpeg-turbo - Browse /2.1.4 at SourceForge.net Package signatures To ensure the integrity of the libjpeg-turbo binary packages, the RPM and DEB files and the source tarball are signed using the following key: http://www.libjpeg-turbo.org/key/LJT-GPG-KEY http://pool.sks-keyservers.net/pk..

코드/C++ 2022.08.23

MFC에서 OpenCV 사용 시 메모리 누수 해결

Lib를 만들고 테스트를 하는데 계속해서 메모리 누수가 생겼다. 메모리 누수가 생길 만큼 복잡한 코드도 아닌데 여지없이 발생한다. 특정 Lib을 포함하면 생기고 제거하면 안 생긴다. 그런데 또 그것만 따로 테스트하면 안 생겼다. 귀신이 곡할 노릇. 이래저래 오전을 다 보낸 뒤 OpenCV를 제거하니 모든 것이 정상이 되었다. 이런 경험은 처럼이라 구글링 해보니 그런 경우가 있다고 한다. 이것은 OpenCV 라이브러리가 로딩되는 시점과, MFC 공용 DLL이 로드되는 시점에 충돌이 발생될 수 있다하여 OpenCV lib을 지연 로딩해야 한다는 것이다. 그래서 지연 로딩에 등록 후 실행하니 메모리 누수가 해결되었다. 참 별일이다. 이런 것 해결하는 분들은 엄지척.. ^^

[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()

728x90
반응형