typedef 는 기존에 존재하는 자료형의 이름에 새 이름(별명)을 부여하는 것을 목적으로 한다.
예를 들어 앞서 선언한 포인터를 이런식으로 선언한다면,
typedef struct point
{
int xPos;
int yPos;
} Point; /* 구조체 선언과 동시에 struct point에 Point 라는 새 이름(별명)을 부여하게 된다. */
int main(void)
{
Point P; /* struct라는 키워드를 생략하고 구조체 변수를 생성할 수 있다.
Point = struct point 처럼 되었다고 생각하면 된다.
P.xPos = 3;
P.yPos = 5;
}
보통 데이터를 묶어 사용할 때 struct를 많이 사용하는데 struct와 typedef struct의 차이점을 모르고 사용하는 경우가 있습니다. 이에 그 차이점을 정리해 보고자 합니다.
struct의 사용법으로 3가지 정도가 있습니다
아래와 같습니다.
1>
typedef struct
{
int data;
int text;
} S1;
// S1이라고 타입정의합니다. C와 C++에서 문제없이 동작합니다.
2>
struct S2
{
int data;
int text;
};
//S2라고 타입정의합니다. 이 형태는 C++에서만 가능합니다. C에서는 Error를 냅니다.
3>
struct
{
int data;
int text;
}S3;
// 이 문장은 C와 C++에서 문제없이 동작합니다.
// 하지만 주의할 점은, S3를 타입정의가 아닌 직접 변수로 선언하게 됩니다. S3자체가 변수입니다.
// 컴파일러는 S3변수를 위한 메모리를 할당하게 됩니다. S1,S2는 타입정의만 하기 때문에 메모리 할당이 당연히 없습니다.
// 사용 예
void main()
{
S1 mine1; // 문제없이 동작합니다. 이때 S1은 typedef입니다.
S2 mine2; // 역시 문제없이 동작합니다. 이때 S2도 역시 typedef입니다.
S3 mine3; // 문제가 발생합니다! S3는 typedef가 아니라 변수입니다. 따라서 S3 mine3;는 옳지 않습니다.
S1.data = 5; // 에러가 발생합니다. S1은 변수가 아닌 typedef입니다.
S2.data = 5; // 역시 에러가 발생합니다. S2는 변수가 아닌 typedef입니다.
S3.data = 5; // 잘 동작합니다. S3자체가 변수이기 때문에 문제가 없습니다.
}
다음으로 linked lists를 사용할 때 차이점을 알아보겠습니다.
1>
struct S6
{
S6* ptr;
};
// 위 문장은 C++에서만 가능합니다. C++ only
// C++에서는 위와같이 linked lists구조로 갈 수 있겠죠.
2>
typedef struct
{
S7* ptr;
}S7;
// 위 문장은 언뜻보면 문제가 없을 것으로 보이지만, 일단 C나 C++에서 에러를 낸다고 합니다.
// 하지만 무조건 에러를 내는것은 아닙니다. 컴파일러가 single-pass 이냐 multi-pass이냐에 따라서 가불이 결정됩니다.
gcc컴파일러 같은 single-pass의 경우 방금 말한 것처럼 저런 구문은 안됩니다. 이유는, S7* ptr; 구문에서 S7의 형태를 미처 파악 못하였기 때문에 에러를 내고 사용할 수 없다고 합니다. 하지만 multi-pass컴파일러의 경우는, 일단 저 문제시되는 부분에서는 에러 대신 unresolved symbol로 해놓고 지나갑니다. 그 후 다시 그 부분을 재처리해서 문제없이 동작하게끔 합니다. 컴파일러의 차이에 의해서 저 구문이 가능할 수도 있고 불가능할 수도 있다는 게 요지입니다.
대안책으론, S7* ptr; 대신 void* ptr;로 대체하고 타입캐스팅을 이용하면 문제없이 저 형태를 쓸 수 있을 것입니다. 그리고 struct대신에 class를 사용해도 문제 해결이 될 것입니다.
이상 간략하게 struct{}와 typedef struct{}에 대하여 알아봤습니다.
일단 새 프로젝트 - MFC - MFC 라이브러리 인가? 그거쓰고 옵션은 MFC 확장 DLL로 줌.
생성하면 거의 새하얀 백지의 코드가 보임.
extern "C" __declspec(dllexport) 뒤에 함수형태.
그리고 기술함.
클래스 형식의 DLL을 델파이에 이식시키기위해서 2주일 동안 쇼를 해봤지만 되지않음.
그래도 방법은 있었다.
DLL의 함수들을 가짜 생성자? 에 쑤셔넣어서 메모리에 등록시키는 법이었다.
extern "C" __declspec(dllexport) int ConstFunction(void)
{
hIns = LoadLibrary("xxxxxx.dll");
a = GetProcAddress(hIns, "DLL내부 함수명");
b = GetProcAddress(hIns, "DLL내부 함수명");
c = GetProcAddress(hIns, "DLL내부 함수명");
}
머 이런식으로 전역변수로 a b c 를 선언하고 메모리할당용 함수를 하나 만들어주면 완료된다.
typedef int ( *a )( int , int ); // a라는 함수포인터를 코드 맨윗줄쯤 추가해줘야 동작하겠지.
소멸자는 FreeLibrary() 로 인스턴스핸들을 인자로 넣어주면 메모리에서 삭제된다.
시박. 이거때문에 내가 2주동안 말도안되는 상상을 해가면서 부풀린 코드만 몇백줄이다.
다른분들은 부디 이런짓 안하길바라면서...
참고로 C++로 만들어진 출처없는 DLL을 다시 DLL로 다듬어서 델파이에 이식시키기 위해서 이짓을하였다.
그리고 알아낸것은 C# 또는 C++로 만들어진 클래스DLL 파일은 델파이에 이식이 불가능(?) 하다고 한다.
확실하진않음.
델파이의 .NET이 지원되는 버전부터 이식이 가능. 그 하위버전에서는 클래스는 무리인듯. 함수로 하길..
'Windows 개발' 카테고리의 다른 글
Win7 64bit Eprocess 구조체 (0) | 2013.08.23 |
---|---|
Write a very small KMDF driver (0) | 2013.08.23 |
Keyboard Filter Driver 제작. ( Key Logger ) (0) | 2013.08.22 |
C# 외부 프로그램 종료하기 / C# Process.GetProcessesByName (0) | 2012.10.12 |
[MFC] 프로그램 안에서 외부 파일을 실행시키기(WinExec, ShellExecute, CreateProcess) (0) | 2012.10.12 |