티스토리 뷰
뭐, 대단한 거에 대한 생각은 아니고 그냥 어떻게 하면 좀 더 DLL을 편하게 쓸까...
이 고민을 조금 해봤다..
일단 확장형DLL은 클래스가 지원이 되지만 일반 DLL은 안된다는 점에서
DLL내에서 값을 유지하려면 전역변수를 쓰는 고통을 남겨야할 듯 하다...
일단은 눈물을 머금고 전역변수를 쓰지만, 대안이 있을 듯 하다..나중에 찾아보자..
뭐, 전역 변수도 될지는 아직 모르겠다...한번 테스트 해보자..
std::vector<float*> g_vecData;
int g_nWindowSize;
int g_nDataSize;
extern "C" __declspec(dllexport) int AddDataToPreprocessor(float* inputData , int dataSize);
int AddDataToPreprocessor(float* inputData , int dataSize)
{
g_nDataSize = dataSize;
g_vecData.push_back(inputData);
if((int)g_vecData.size() > g_nWindowSize)
{
g_vecData.erase(g_vecData.begin());
}
return (int)g_vecData.size();
}
if((int)g_vecData.size() > g_nWindowSize)
{
g_vecData.erase(g_vecData.begin());
}
return (int)g_vecData.size();
}
dll안에 이런 함수를 만들어봤다.. 만약에 전역변수가 허용이 된다면 return값이 점점 늘어나겠지..
g_nWindowSize는 초기값을 10으로 초기화 한다..이것은 DllMain안에서 했는데, 지금은 인자에 따라 다른 처리를 해주면 좋을 것 같은데, 다음에 좀더 자세하게 살펴보면 좋을 것 같다..
res = ((int (*)(float* , int))procAddData)(NULL , 3);
res = ((int (*)(float* , int))procAddData)(NULL , 3);
res = ((int (*)(float* , int))procAddData)(NULL , 3);
어제의 소스에 이렇게 테스트를 해보자.. 첫줄에서 컨트롤+F10!
여기서..
이렇게만 바뀌고 바뀌는게 없다...이런! windowSize에서 뭔가 잘못 된듯..
이렇게 바꾸고 다시 도전..
int g_nWindowSize = 10;
이제 제대로 된다! 전역변수도 잘 들어가고...DllMain가 초기화할 때 호출 되는거라고 들었는데 뭔가 좀 다른가보다..DllMain을 통해서 초기화하는것도 알아봐야겠다..
그럼 이제 부터 클래스에 때려넣는거를 해보자..먼저, 핸들 인스턴스를 클래스가 가지고 있어야하므로 전역 변수 선언..
// 전처리 라이브러리 핸들러
HINSTANCE m_hinstPreprocessor;
이제 클래스안에다 넣어보자..먼저 LoadLibrary는 초기화 단계에 넣고 FreeLibrary는 해제하는 함수에 넣고...이왕하는거 보기 좋게 LoadPreprocessor()함수를 따로 만들어서 쓰자..
해제는 간단하다..
// Unload DLL file
if(this->m_hinstPreprocessor != NULL)
FreeLibrary(this->m_hinstPreprocessor);
생성 부분에서는 활용할 함수들을 정의하고 로드해야한다..
(그냥...여기서 드는 생각..vector는 어짜피 c형이니 전처리를 할 때 dll에서 인자를 아예 vector형으로 받는 것은 어떨까...뭐, 일반성이 조금 떨어지긴 하지...그럼 float**의 형태로 인자를 받도록 변환하고 따로 Preprocessor 클래스에 vector형을 만들면 어떨까....하지만 이렇게 하면 dll이외에 설정해줘야하는게 생기므로 패스...그냥 눈물을 머금고 전역변수 쓰자 ㅠㅠ)
이렇게 된거 좀 수정하자...Preprocessor클래스를 만들어서 그 안에 라이브러리 로드,해제, 함수호출, 함수 할당까지 다 때려 넣자...Dlg에 이런거 들어가는게 객체지향적인 마인드에 위배되기도 하지!-_- 다시 새로운 클래스 Preprocessor 안으로 이동..
재밌는게 dll에서 호출할 함수는 클래스 안에다가 함수를 추가하는게 아니라 함수 포인터를 추가하는 것이므로 변수를 추가하는 것이고 변수형이
int(*)(float* , int)
라는것..보통 포인터는 m_p.. 를 달아주는게 버릇이지만, 이건 그냥 함수처럼 쓰도록 해보자..
다음과 같이 했다..
Preprocessor::Preprocessor(void)
: AddData(NULL)
{
this->m_hinstPreprocessor = LoadLibrary(L"Preprocessor.dll");
if (this->m_hinstPreprocessor == NULL) {
//에러 처리
return;
}
// Get function pointer
FARPROC procAddData = GetProcAddress(hinstLib, "AddDataToPreprocessor");
if (procAddData == NULL) {
//에러 처리
FreeLibrary(this->m_hinstPreprocessor);
return;
}
this->AddData = (int(*)(float* , int))procAddData;
}
FARPROC procAddData = GetProcAddress(hinstLib, "AddDataToPreprocessor");
if (procAddData == NULL) {
//에러 처리
FreeLibrary(this->m_hinstPreprocessor);
return;
}
this->AddData = (int(*)(float* , int))procAddData;
}
Preprocessor::~Preprocessor(void)
{
// Unload DLL file
if(this->m_hinstPreprocessor != NULL)
FreeLibrary(this->m_hinstPreprocessor);
{
// Unload DLL file
if(this->m_hinstPreprocessor != NULL)
FreeLibrary(this->m_hinstPreprocessor);
}
함수 포인터는 AddData이고, 에러처리는 귀찮아서 아직 안했다;; 이런 귀차니즘 안되는데..버릇되는데...-_-
그럼 다시 테스트! Dlg의 OnInitDialog안에 m_pPreprocessor를 초기화 시켜주고 OnDestroy안에다가 delete m_pPreprocessor를 넣어주고..바로 활용할 수 있게 데이터 측정하는 OnTimer에 넣어보자...
호출이 아주 쉽다..
// int dataSize = this->m_pPreprocessor->AddData(float* , int); 로 호출하면 됨
int dataSize = this->m_pPreprocessor->AddData(data , this->m_ucLogData.m_nDataNumber);
'애개?'라는 생각이 들정도로 쉽다! dll에서 패키지로 그냥 Preprocessor라는 클래스까지 제공해준다면 너무나 편할것 같다! 뭐, 그건 사용할 사람들이 알아서 할 내용이고, 어쨋든 다시 ctrl+f10!
잘 들어간다! AddData도 dll안에 있던 함수의 포인터로 잘 할당 되었고! 이제는 Preprocessor의 컨스트럭터안에다가 모든 함수들을 설정해서 함수처럼 사용할 수 있도록 하는 일만 남았다. 클래스하나를 통해서 dll이 마치 내것(?)인냥 마구 쓸 수 있으니 만족!!
또 다른 방법도 도전해볼까? 변수명이니까 왠지 헷갈리는거 같으니깐 함수에다가 포인터를 설정해보자+_+ 이것도 될지 안될지는 모르겠다-_-
int &(Preprocessor::AddData2)(float* , int) = (int(*)(float* , int))procAddData;
안된다-_-될것 같지도 않은데 그냥 해봤다;;여러 가지 해보다가 검색해보니..
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.1
에서 다른 방법을 돌려서 쓰는 방법은 나와있다..바로는 안되나보군...그럼 그냥 쓰자-_-;
검색하다가 함수포인터와 관련된 재밌는 내용을 찾았다..
http://www.goingware.com/tips/member-pointers.html#not-addresses
같은 입력에 호출하고자하는 함수가 다를 경우 멤버 함수 포인터를 쓰는 부분..뭐, 그닥 실용적인것 같지는 않지만, 뭔가 있어보인다-_-;;
멤버 함수 포인터 이외에 기본적인 퍼포먼스 관련된 내용들도 있으니 나름 참고할만하다...
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- ny-school
- gre
- Javascript
- 자바스크립트
- 안드로이드
- 뽐뿌
- 강좌
- 안드로이드 앱 개발 기초
- Writing
- 속깊은 자바스크립트 강좌
- 샷
- HTML5 튜토리얼
- Android
- 삼식이
- c++
- TIP
- 사진
- gae
- google app engine
- HTML5
- K100D
- java
- 팁
- Python
- lecture
- 서울
- GX-10
- mini project
- php
- 탐론 17-50
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함