본문 바로가기

Development Experience

(85)
Telerik Winform에서 border의 색깔이 도저히 안 없어질때.. RadPanel 의 Border 색깔을 지우고 싶었는데 이짓 저짓 다 해보아도 사라지지 않았다. BorderThickness, BorderHightLightThickness, BorderColor, BorderHightLight 다 건드려봤지만 없어지지 않았다. 결국 찾은 방법은 RadPanel의 Telerik 속성에 들어간 다음, Element Hierarchy에서 BorderElement, 혹은 BorderPrimitive의 속성을 찾아서 ShouldPaint 속성을 false로 설정하여 해결하였다. 누군가가 나와 같은 고통을 받고 있다면 그 객체의 Hierarchy에서 수정할 수 있는 녀석들이 있는지 찾아보자.
LNK2019 에러가 날 때.. LNK 는 링크 관련 에러이다. 보통 오브젝트 파일을 생성한 후 링킹을 시도하면서 특정 파일을 찾지 못하는 경우 발생한다. 문제를 해결하기 위해 Visual Studio 의 Project 를 마우스 우클릭 > Properties > 창 왼쪽 영역의 Configuration Properties > Linker > General 을 들어간 후 Additional Library Directories 에서 참조하는 파일을 추가하면 된다. 이 방법 말고 또 하나의 방법이 있는데, 바로 코드 상에서 #pragma comment(...)를 삽입하는 것이다. 나의 경우, A 프로젝트를 참고하여 B 프로젝트를 만들고 있었는데 분명 Additional Library Directories가 동일함에도 내 프로젝트 에서는 L..
DLL이 경로에 있음에도 DLLNotFound Exception이 뜬다면.. C# 프로그램에서 C++로 작성된 DLL 파일을 로드하려했는데(DllImport) DllNotFoundException 오류가 발생하였다. 찾아보니 C#에서 C++ DLL을 로드하기 위해선 1. C#의 빌드 형식과 C++ DLL의 빌드 형식이 맞아야 한다. 즉, x86이면 x86끼리, x64면 x64끼리 로드해야 한다는 얘기. 2. 같은 경로에 있어야 한다. 3. 함수 호출 스택 (cdecl 인지, stdcall 인지) 이 맞아야 한다. 즉, C++ DLL의 호출 스택이 cdecl이면 C# 에서도 cdecl로, stdcall 이면 stdcall로 받아주어야 한다. 4. C++ DLL에서 extern "C"를 선언해야 한다. 위와 같은 조건이 맞아야 한다. 위의 4가지를 다 해봤는데도 안되었다... 그러다..
C++ <-> C# 간 마샬링 시 메모리 할당 및 해제 Win32 API 중 메모리 할당 및 해제를 할 때 LocalAlloc(), LocalFree() 함수를 사용한다. C++ C# 간 마샬링을 할 때 한 쪽에서 LocalAlloc()을 통해 메모리를 할당하고, 다른 한 쪽에서 LocalFree()를 통해 메모리 해제가 가능하다. C#에선 마샬링할 때 Marshal.AllocHGlobal() 을 많이 사용하는데, 이 함수 내부는 Win32 함수인 LocalAlloc()을 호출하는 식으로 구성되어 있다. LocalAlloc(), LocalFree() 와 같은 역할을 하는 Win32 함수로 CoTaskMemAlloc(), CoTaskMemFree() 가 있다. LocalAlloc(), LocalFree() 가 C#의 Marshal.AllocHGlobal(), ..
C# Memory Leak 해결 툴 Memory Leak을 측정하는 방식 중 2가지를 발견하였다. 하나는 perfMon을 사용하는 방식이고, 다른 하나는 Memory Profiler를 사용하는 방식이다. [ perfMon ] 1. Task Manager 는 정확한 성능 상태를 측정하지 못한다. 사용하는 메모리가 아닌 할당된 메모리를 보여주고 그마저도 다른 프로세스에서 사용하고 있을 수 있다. 2. 프로세스에서만 사용하는 메모리를 보기 위해서 private bytes 를 보아야 한다. 이는 performance counter를 통해 볼 수 있다. 3. 메모리 릭이 발생한다면 3가지를 알아보아야 한다. 1) What ? managed 메모리 릭인지, unmanaged 메모리 릭인지 2) How ? connection object 때문인지, 파..
Error Message: 식에 정수 또는 범위가 지정되지 않은 열거형 형식이 있어야 합니다 식 (1983 * 214013 + 2531011) % (2^32) 에서 %(모듈러) 연산을 수행하려 하는 중 이 에러가 발생하였다. 모듈러 연산은 정수형에 대해서만 수행 가능한데, 나는 double 형으로 수행하려고 하였기 때문이다. C++ 에서 2^32 를 구하기위해 pow(2, 32)를 사용하였고, 이 리턴값이 double 형인 것이다. 일반적으로 이 에러가 발생하였다면 간단히 double형 변수가 있는 자리에 int형 변수를 넣으면 된다. 나도 단순히 double 형을 int 형으로 캐스팅하려 했는데.. 생각해보니 2^32 라는 int형 범위를 넘어버리는 것이다. 심지어 unsigned int 형 범위도 2^32 - 1 까지다. 살짝 멘붕이 왔다. % 를 쓰기 위해선 정수형으로 연산해야 하는데, 연..
C# Enum 을 int 로 캐스팅하는 효율적인 방법 [ 이슈 ] 클라이언트에서 관리하고 있는 Enum 형식의 데이터들을 서버로 전송해야되서 Enum 형을 int 형으로 캐스팅하려고 한다. 이 경우 바로 캐스팅하여 (int)EnumKind.EnumData1; 처럼 사용하면 될 것 같지만, Enum 형을 바로 int로 캐스팅할 경우 성능 저하가 발생한다. 성능저하를 최대한 줄이면서 캐스팅할 순 없을까? [ 배경 지식 ] 1. 박싱 / 언박싱 C#에서는 데이터 형식을 값 형식과 참조 형식으로 나눈다. 값 형식은 스택 영역에 데이터가 생성되고, 참조 형식은 힙 영역에 데이터가 생성되는 차이점이 있다. 박싱이란 값 형식을 참조 형식으로 변환하는 행위이고 (스택 영역의 데이터를 힙 영역으로 복사), 언박싱은 반대로 참조 형식을 값 형식으로 변환하는 행위이다. (힙 ..
C# Error Message : Cannot modify the return value of 'Collection<...>' because it is not a variable Collection이 구조체(struct) 로 이루어져 있으면, Collection의 element에 접근해서 값을 변경하는 작업 시 에러가 난다. Collection의 값을 변경하려고 참조하는 순간 element의 복사가 이루어지고(element가 struct 이니까), 복사된 객체에 아무리 이런저런 수정을 하더라도 원본은 변경되지 않기 때문이다. 그래서 컴파일러가 애초에 의미없는 행동이라고 에러를 내뱉게 된다. 같은 이유로 struct로 이루어진 List도 element를 수정할 수 없다.