'Programming Skill'에 해당되는 글 40건
- 2016.08.24 ios task worker
- 2013.01.04 C++ 0x (tr1) function, bind 를 이용해 타클래스 펑션 변수에 저장하기 1
- 2013.01.04 C++ 0x (tr1) - 클로저 흉내내기 (라고 쓰고 구현하기 라고 읽는다..)
- 2011.06.17 c# > Deserialize 에서 SerializationException 어셈블리를 찾을 수 없습니다.. 1
- 2011.02.16 LFH
- 2011.01.05 대용량 FTP 파일 업로더 / 다운로더 3
- 2010.09.29 상속받아 쓰는 옵저버 패턴 템플릿
- 2010.09.29 상속받아 쓰는 싱글턴 패턴 템플릿
- 2010.09.06 Safe TerminateProcess()
- 2010.05.18 템플릿을 활용한 클래스간 제약없이 함수포인터 등록 / 사용
class A {
public:
templete< typename T>
void set(T* fnClass, void(T:: *fn)(unsigned int, float, void*), unsigned int _i, float _f, void* p) {
fn = std::tr1::bind(fn, fnClass, _1, _2, _3);
i = _i;
f = _f;
p = _p;
}
std::tr1::function<void (unsigned int, float, void*)> fn;
unsigned int i;
float f;
void* p;
}
class B {
B(){
a.set(this, &B::Callback, 0, 0, 0);
}
void Callback(unsigned int i, float f, void* p) { }
private:
A a;
}
#include <algorithm> #include <iostream> #include <vector> #include <functional> using namespace std; class Foo { public: Foo(void) { for(int i = 0; i < 1000; i++) v.push_back(i); } void process(function<void(int)> f) { for(std::vector<int>::iterator i = v.begin(); i != v.end(); i++) f(*i); } private: vector<int> v; }; int main() { int evenCount = 0; Foo f; f.process(function<void (int)>([&evenCount](int n) { cout << n; if(n % 2 == 0) { cout << " is even" << endl; evenCount += 1; } else { cout << " is odd" << endl; } })); // Print the count of even numbers to the console. cout << "There are " << evenCount << " even numbers in the vector." << endl; return 0; }
해결방법 :
01 |
sealed class AllowAllAssemblyVersionsDeserializationBinder : System.Runtime.Serialization.SerializationBinder |
02 |
{ |
03 |
public override Type BindToType( string assemblyName, string typeName) |
04 |
{ |
05 |
Type typeToDeserialize = null ; |
06 |
07 |
String currentAssembly = Assembly.GetExecutingAssembly().FullName; |
08 |
09 |
// In this case we are always using the current assembly |
10 |
assemblyName = currentAssembly; |
11 |
12 |
// Get the type using the typeName and assemblyName |
13 |
typeToDeserialize = Type.GetType(String.Format( "{0}, {1}" , |
14 |
typeName, assemblyName)); |
15 |
16 |
return typeToDeserialize; |
17 |
} |
18 |
} |
19 |
20 |
public static MyRequestObject Deserialize( byte [] b) |
21 |
{ |
22 |
MyRequestObject mro = null ; |
23 |
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); |
24 |
System.IO.MemoryStream ms = new System.IO.MemoryStream(b); |
25 |
26 |
// To prevent errors serializing between version number differences (e.g. Version 1 serializes, and Version 2 deserializes) |
27 |
formatter.Binder = new AllowAllVersionsDeserializationBinder(); |
28 |
29 |
// Allow the exceptions to bubble up |
30 |
// System.ArgumentNullException |
31 |
// System.Runtime.Serialization.SerializationException |
32 |
// System.Security.SecurityException |
33 |
mro = (MyRequestObject)formatter.Deserialize(ms); |
34 |
ms.Close(); |
35 |
return mro; |
36 |
} |
출처:
http://spazzarama.wordpress.com/2009/06/25/binary-deserialize-unable-to-find-assembly/
HANDLE Heaps[1025]; DWORD count = GetProcessHeaps(1024, Heaps); ULONG HeapFlagValue = 2; for(int i = 0; i < count; i++) { HeapSetInformation(Heaps[i], HeapCompatibilityInformation, HeapFlagValue, sizeof(HeapFlagValue)); }
template <class T, class T_ObjReturn> class CallFunc { public: CallFunc(T_ObjReturn (T::*pfunc)(int, float, void*), int nparam, float fparam, void* lparam) : IFunc(pfunc), nParam(nparam), fParam(fparam), lParam(lparam) { } T_ObjReturn operator()(T *pClass) const { return ((pClass->*IFunc)(nParam, fParam, lParam)); } private: T_ObjReturn (T::*IFunc)(int, float, void*); int nParam; float fParam; void* lParam; }; template <class T> class CObservable { public: CObservable() {} virtual ~CObservable() { m_listObserve.clear(); } void addObserveObj (T* obj){ m_listObserve.push_back(obj); } void removeObserveObj(T* obj){ m_listObserve.remove(obj); } void removeObserveAll() { m_listObserve.clear(); } ///------------------------------------------------------------------------- protected: template <class T_ObjReturn> void ObserveCall(T_ObjReturn (T::*pfunc)(int, float, void*), int nparam = 0, float fparam = 0, void* lparam = 0) { std::for_each( m_listObserve.begin(), m_listObserve.end(), CallFunc<T, T_ObjReturn>(pfunc, nparam, fparam, lparam)); } ///------------------------------------------------------------------------- protected: std::list<T*> m_listObserve; }; class IEventObservable { public: IEventObservable() {} virtual ~IEventObservable() {} virtual void ContextCall(int nparam, float fparam, void* lparam) = 0; };
template <typename T> class CSingleton { static T* ms_Singleton; public: CSingleton(void) { assert(!ms_Singleton); int offset = (int)(T*)1 - (int)(CSingleton <T>*)(T*)1; ms_Singleton = (T*)((int)this + offset); } ~CSingleton(void) { assert(ms_Singleton); ms_Singleton = 0; } static T* GetSingleton(void) { assert(ms_Singleton); return ms_Singleton; } static T* GetSingletonPtr(void) { if(ms_Singleton == NULL) { return ms_Singleton; } assert(ms_Singleton); return ms_Singleton; } static T& GetSingletonInstance(void) { assert(ms_Singleton); return(*ms_Singleton); } }; template <typename T> T* CSingleton <T>::ms_Singleton = 0;
고수닷넷 - snaiper님
TerminateProcess 를 사용해도 되는건지...
Win32 API 에 보면 TerminateProcess 라는 함수가 있습니다. 함수명 그대로 Process 를 강제로 Kill 시키는 함수입니다. 하지만 Jeffery Richter 의 Programming Application for Win2k 나 기타 이와 관련된 설명을 하는 책이면 되도록 쓰기를 권고하지 않는 함수로서 설명하고 있습니다. 이유는 여러가지 있습니다만 그 중에 한 이유를 소개하면 여러 리소스 정리가 되지 않고 바로 죽기 때문입니다.
그럼 어떻게 하나?
쓰지 말라고 하였으니 안 쓰면 되지 하겠지만, 그런데 꼭 쓸 경우가 생깁니다.
만약 위의 권고를 이미 알고 있는 사용자라면 더욱 고민하겠지요. 결국 권고를 무시하고 쓰는 경우가 많은데, 이를 위해 더 안전한 방법을 소개 합니다. 이 방법은 이미 DDJ 에 소개된 방법입니다만 모르는 분이 많은 것 같아 소개합니다.
사용법은 아래와 같이 함수를 작성하고 TerminateProcess 와 똑같이 호출해주시면 됩니다.
{
DWORD dwTID, dwCode, dwErr = 0;
HANDLE hProcessDup = INVALID_HANDLE_VALUE;
HANDLE hRT = NULL;
HINSTANCE hKernel = GetModuleHandle("Kernel32");
BOOL bSuccess = FALSE;
BOOL bDup = DuplicateHandle(GetCurrentProcess(),
hProcess,
GetCurrentProcess(),
&hProcessDup,
PROCESS_ALL_ACCESS,
FALSE,
0);
if ( GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode)
&& (dwCode == STILL_ACTIVE) )
{
FARPROC pfnExitProc;
pfnExitProc = GetProcAddress(hKernel, "ExitProcess");
hRT = CreateRemoteThread((bDup) ? hProcessDup : hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)pfnExitProc,
(PVOID)uExitCode, 0, &dwTID);
if ( hRT == NULL ) dwErr = GetLastError();
}
else
{
dwErr = ERROR_PROCESS_ABORTED;
}
if ( hRT )
{
WaitForSingleObject((bDup) ? hProcessDup : hProcess, INFINITE);
CloseHandle(hRT);
bSuccess = TRUE;
}
if ( bDup )
CloseHandle(hProcessDup);
if ( !bSuccess )
SetLastError(dwErr);
return bSuccess;
}
위의 소스 코드를 분석해보면 원리는 간단합니다. Kernel32.dll 에 있는 ExitProcess라는 함수에 대한 포인터를 얻고 그것을 CreateRemoteThread를 이용하여 호출하여 그 프로세스가 스스로 죽는 효과를 만들어 내는 것입니다.
물론 DuplicateHandle 등 부수적인 체크 등을 위해 넣은 코드들은 있지만 기본 원리는 이와 같이 간단합니다.
이를 사용할 때의 주의점은 Win9X 계열은 이 방법을 사용할 수 없다는 점입니다. CreateRemoteThread 라는 API 를 사용하는데 이것은 Win9X 에서는 지원하지 않는 함수이므로 사용할 수 없는 것입니다. 따라서 이 점 주의해주십시오.
template<class T>
public:
CPfunc(T* fnclass)
{
FnClass = fnclass;
(FnClass->*fn)()
}
virtual ~CPfunc(){ }
private:
T* FnClass;
func fn;
};