https://msdn.microsoft.com/ko-kr/library/h90dkhs0(v=vs.90).aspx
=============================================
출처- 하기 블로그에서 참고하였으며, 문제가 되면 삭제하겠습니다.
http://legendfinger.tistory.com/449
=============================================
공유 메모리
일반적으로 exe나 DLL안의 전역변수들은 기본적으로 PAGE_WRITECOPY 속성이 지정되기 때문에 쓰기전에 복사본이 만들어진다(Copy-On-Write) 그러므로 A와 B는 둘 다 다른 물리 공간을 사용하게 된다.
하지만 DLL내에 공유 메모리를 만들어 사용하면 서로 다른 2개의 프로세스가 DLL내의 공유 메모리를 사용해서 통신할 수 있다.
DLL 공유 섹션 만드는 방법
#pragma data_seg("SHARED")
char shared_buffer[1024] = {0};
#pragma data_seg()
#pragma comment(linker, "/subsystem:SHARED,RWS")
단점(보안에 취약하다)
DLL은 Kernel Object의 보안속성을 줄수 없으므로 다른 프로세스에서 DLL을 로드하여 데이터를 가로챌수있다.(보안에 상관없는 통신에서 사용해야한다)
--------------------------------- X.dll -------------------------------------
공유 메모리 설정 DLL 파일
구성 파일 : X.h, a.cpp
X.h
// X.h
#include <windows.h>
#ifdef DLLSOURCE
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif
EXTERN_C DLLAPI void Set(int);
EXTERN_C DLLAPI int Get();
//--------------------------------------------------
a.cpp
// a.cpp
#define DLLSOURCE
#include "X.h"
// DLL 안에 공유 메모리를 만들면 이 DLL을 사용하는 모든 프로세스에서
// 공유 할 수 있다.
#pragma data_seg("SHARE")
int x = 0; // 주의! 반드시 초기화된 data만 공유 메모리에
// 들어갈수있다.
#pragma data_seg()
#pragma comment(linker, "/section:SHARE,RWS")
// " "안에 띄여쓰기 하지 마라
void Set(int value)
{
x = value; // 공유 메모리를 변경한다
}
int Get()
{
return x;
}
----------------------- AA.exe ------------------------------
공유메모리에 값을 할당하는 프로그램
#include <windows.h>
#include <stdio.h>
// X.h와 X.lib 복사해 와라
#include "X.h"
#pragma comment(lib, "X.lib")
void main()
{
HANDLE hEvent = CreateEvent(0, 0, 0, "e");
while(1)
{
int n = 0;
printf("숫자를 넣으세요 >>");
scanf("%d", &n);
Set(n); // DLL 안에 있는 공유 메모리에 data를 넣는다
SetEvent(hEvent);
}
}
// X.h와 X.lib는 현재 폴더에 복사해오세요
// X.dll은 c:\\winnt 아래에 복사해두세요
// - BB프로세스와 공유하기 위해
------------------------------ BB.exe ---------------------------------
공유 메모리 값을 출력하는 프로그램
#include <windows.h>
#include <stdio.h>
// X.h와 X.lib 복사해 와라
#include "X.h"
#pragma comment(lib, "X.lib")
// DLL 안에 공유 메모리를 사용한 IPC 기법
void main()
{
HANDLE hEvent = CreateEvent(0, 0, 0, "e");
while(1)
{
WaitForSingleObject(hEvent, INFINITE);
int n = Get();
printf("X 값 : %d\n", n);
}
}
// X.h와 X.lib는 현재 폴더에 복사해오세요
// B를 먼저 실행하고
// A를 실행 해보세요
// A에 값을 넣고 Enter
=============================================
출처- 하기 블로그에서 참고하였으며, 문제가 되면 삭제하겠습니다.
=============================================
callback 함수를 알아보기 전에..
먼저 함수를 가리키는 포인터를 만들어서 그 포인터로 어떤 함수를 호출하는 방법에 대해 알아보자.
먼저 다음과 같이 type def를 한다.
typedef int (*func) (int);
이렇게 하면, func는 int를 return하고 int를 인자로 받아들이는 함수를 가리키는 포인터의 형이 된다.
이와 같은 형태의 함수면 어떤 거든 포인트 할 수가 있다.
예를 들어
int example_function(int param1)
{
printf("%d",param1);
}
다음과 같은 함수가 있다면,
func pointer_to_func;
pointer_to_func = example_function;
pointer_to_func(5);
이것은 곧...
example_function(5); 와 동일한 결과를 낳는다.
여기까지가...
함수에 대한 포인터를 만들어서 이 포인터로 함수를 호출하는 방법에 해당한다....
그러면 DLL에서를 생각해보자. DLL이 쓰이는 상황은,
User Program 과 DLL로 나눠서 생각을 해봐야 한다.
DLL에 함수들이 잔뜩 있으며, User Program에 함수가 잔뜩 있다.
우리는 DLL에서 User Program의 함수를 호출하게끔 만들고 싶을 수 있다.
특정 파라메터를 가지고 DLL에서 user Pgoram의 함수를 호출하게 하여
통신 비스므리한 효과를 내는 것이다.
이를 위해서는 그림에서 보다시피,
User Program에서는 그렇게 호출받기 원하는 함수를 정의한다. 함수1이 정의 되었으면,
DLL에 있는 레지스터콜백을 위한 함수에다 이 함수의 이름(포인터)를 넘겨주면
콜백이 등록이 되는 것이다.
그러면, DLL에서는, 이렇게 넘겨온 함수에 대한 포인터를 가리킬 전역변수를 하나 만들고(func callbackFunc
DLL레지스터콜백에서는 넘겨온 함수의 포인터를 callbackFunc에 배정을 시킨다.
그러면 어떤다른 함수에서 user Program의 특정 함수를 호출해야 겠다 싶으면,
callbackFunc()를 호출하면 user Program에서 지정한 함수가 호출되게 되는 것이다.
'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글
C++ typeid 변수 타입 알기 (0) | 2019.05.13 |
---|---|
wsprintf 부동 소숫점 표현하기 (0) | 2019.05.04 |
w_char (TCHAR) 가변인수 만들기 (0) | 2016.04.29 |
C++11 STL thread 처리 관련 (0) | 2016.04.05 |
바이트 정렬(Byte Alignment) pragma pack(1) (0) | 2015.11.20 |