Introduction

Visual Studio Macro 몇가지 예제를 통해 활용에 관한 내용을 다뤄 봅니다.

보시다시피 VS 매크로는 초딩 정광짱도 하는 VB 스크립트로 되어 있습니다.

Visual Studio .NET 2003을 기준으로 설명하겠습니다.

 

.h/.cpp 파일 전환

    ' if this file is a .cpp then open up the .h 
    '  or vice versa
    Sub OpenPartnerFile()
        Dim filename As String
        Dim partnerFilename As String
        filename = DTE.ActiveDocument.FullName
        If (filename.EndsWith(".h")) Then
            partnerFilename = filename.Substring(0, filename.Length() - 2) + ".cpp"
        End If
        If (filename.EndsWith(".cpp")) Then
            partnerFilename = filename.Substring(0, filename.Length() - 4) + ".h"
        End If
        DTE.ItemOperations.OpenFile(partnerFilename)
    End Sub

 

이 매크로는 Visual Assist Alt+O와 동일한 기능입니다.

'DTE'는 스크립트를 통해 Visual Studio IDE와 통신할 수 있는 자동화 객체입니다.

위의 예제에서 DTE.ActiveDocument.FullName는 현재 열린 파일의 풀패스를 가리킵니다.

DTE.ItemOperations.OpenFile 메써드로 지정한 파일을 열 수 있습니다.

 

다음과 같이 사용자 정의 매크로를 추가할 수 있습니다:

1. 도구->매크로->매크로 IDE(Alt+F11)

2. 프로젝트 탐색기에서 MyMacros를 선택합니다.

3. 오른쪽 버튼을 눌러서 추가->모듈 추가를 선택합니다. 모듈 이름은 알아서 입력합니다.

4. 위의 예제를 복사치기하고 저장합니다.

5. 매크로 탐색기에서 추가한 매크로(OpenPartnerFile)를 더블클릭하여 실행할 수 있습니다.

 

다음과 같이 매크로의 단축키를 지정할 수 있습니다:

1. 도구->사용자 지정->키보드

2. 그림과 같이 지정할 매크로를 선택합니다.

3. 바로 가기 키 누르기를 클릭하고 단축키를 입력합니다.

4. 할당 버튼을 눌러서 등록합니다.

 

Macros for Calling External Tools

간혹 현재 열린 파일을 아구먼트로 넘겨서 외부 프로그램을 실행해야할 경우가 있습니다. 있다고 칩시다.

다음 예제에서 메모장을 실행하는 방법을 알아 보겠습니다.

 

    Sub OpenNotepadCurFile()
        Dim filename As String = DTE.ActiveWindow.Document.FullName
        Dim commandString = "notepad.exe """ + filename + """"
        'MsgBox(commandString)
        ChDir("d:\windows\system32")
        Shell(commandString, AppWinStyle.NormalFocus, True, 100)
    End Sub

 

ChDir("d:\windows\system32")는 Notepad.exe가 있는 시스템 폴더로 이동합니다.

Shell 명령으로 메모장을 실행합니다. 파라메터는 보면 그냥 압니다.

 

Macros that Communicate with the Code Editor

소스 편집기의 내용을 조작하는 예제를 보시겠습니다.

다음은 선택 영역을 중괄호로 감싸고 들여쓰기하는 예제입니다.

 

    ' Takes the current selection, indents it, and surrounds with braces.
    Sub CreateCodeBlock()
        CreateCodeBlock_Helper("{", "}")
    End Sub

 

    ' Takes the current selection, indents it, and surrounds it with startOfBlock and endOfBlock
    Sub CreateCodeBlock_Helper(ByVal startOfBlock As String, ByVal endOfBlock As String)
        Dim sel As TextSelection = DTE.ActiveDocument.Selection
        Dim objAnchor As VirtualPoint = sel.AnchorPoint
        Dim bottomPoint As VirtualPoint = sel.BottomPoint

        Dim trimmedString As String = sel.Text.TrimStart()
        Dim numChars As Integer = sel.Text.Length - trimmedString.Length
        Dim spaceString As String = sel.Text.Substring(0, numChars)

        objAnchor.CreateEditPoint().Insert(spaceString + startOfBlock + vbCrLf)
        bottomPoint.CreateEditPoint().Insert(spaceString + endOfBlock + vbCrLf)
        sel.Indent()

        'sel.LineUp()
        'sel.Text = "{" + vbCrLf + sel.Text + "}" + vbCrLf
    End Sub

 

다음은 이름과 날짜를 입력하는 예제입니다:

 

    ' Inserts name and date
    Sub Signature()
        Dim sel As TextSelection = DTE.ActiveDocument.Selection
        sel.Insert("// Seungwoo Oh ")
        sel.Insert(Format(Date.Today, "yyyy-MM-dd"))
        sel.Insert(".")
    End Sub

 

다음은 수평 라인 주석을 입력하는 예제입니다:

 

    Sub InsertHorizontalLine()
        Dim lineString = "//----------------------------------------------------------------------------" + vbCrLf
        Dim sel As TextSelection = DTE.ActiveDocument().Selection()
        sel.Text() = lineString
    End Sub

 

System.Guid 객체로 GUID를 생성할 수도 있습니다.

 

    REM Insert a new Guid at whatever the cursor has selected
    Sub InsertGuid()
        Dim ts As TextSelection = DTE.ActiveDocument.Selection
        Dim guid As System.Guid = System.Guid.NewGuid()
        ts.Insert(guid.ToString().ToUpper())
    End Sub


Conclusion

Visual Studio는 매우 융통성있는 매크로 언어를 제공합니다.

파일 및 프로젝트 작업시 IDE의 내부 지식은 상당히 효과적입니다.

 

 

출처: Visual Studio Macros for the Game Programmer by Mike Cline

블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

다음은 "윈도우 환경에서 특정 포트를 리슨하고 있는, 프로세스의 정보 조회 방법"에 대해서 설명하고 있습니다.

#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <string.h>

#if defined NTDDI_VERSION && (NTDDI_VERSION >= NTDDI_LONGHORN)
#  include <Iphlpapi.h>
/* Windows Vista Higher                 */
#else

#  ifndef ANY_SIZE
#    define ANY_SIZE 1
#  endif

    /* for Windows 2K, Windows XP, Windows 2003 */
    typedef struct _MIB_TCPROW_OWNER_PID
    {
        DWORD       dwState;
        DWORD       dwLocalAddr;
        DWORD       dwLocalPort;
        DWORD       dwRemoteAddr;
        DWORD       dwRemotePort;
        DWORD       dwOwningPid;
    } MIB_TCPROW_OWNER_PID, *PMIB_TCPROW_OWNER_PID;

    typedef struct _MIB_TCPTABLE_OWNER_PID
    {
        DWORD                dwNumEntries;
        MIB_TCPROW_OWNER_PID table[ANY_SIZE];
    } MIB_TCPTABLE_OWNER_PID, *PMIB_TCPTABLE_OWNER_PID;

    typedef struct _MIB_TCP6ROW_OWNER_PID
    {
        UCHAR           ucLocalAddr[16];
        DWORD           dwLocalScopeId;
        DWORD           dwLocalPort;
        UCHAR           ucRemoteAddr[16];
        DWORD           dwRemoteScopeId;
        DWORD           dwRemotePort;
        DWORD           dwState;
        DWORD           dwOwningPid;
    } MIB_TCP6ROW_OWNER_PID, *PMIB_TCP6ROW_OWNER_PID;

    typedef struct _MIB_TCP6TABLE_OWNER_PID
    {
        DWORD                   dwNumEntries;
        MIB_TCP6ROW_OWNER_PID   table[ANY_SIZE];
    } MIB_TCP6TABLE_OWNER_PID, *PMIB_TCP6TABLE_OWNER_PID;

    typedef struct _MIB_UDPROW_OWNER_PID {
        DWORD dwLocalAddr;
        DWORD dwLocalPort;
        DWORD dwOwningPid;
    } MIB_UDPROW_OWNER_PID, *PMIB_UDPROW_OWNER_PID;

    typedef struct _MIB_UDPTABLE_OWNER_PID
    {
        DWORD                   dwNumEntries;
        MIB_UDPROW_OWNER_PID    table[ANY_SIZE];
    } MIB_UDPTABLE_OWNER_PID, *PMIB_UDPTABLE_OWNER_PID;

    typedef struct _MIB_UDP6ROW_OWNER_PID {
        UCHAR           ucLocalAddr[16];
        DWORD           dwLocalScopeId;
        DWORD           dwLocalPort;
        DWORD           dwOwningPid;
    } MIB_UDP6ROW_OWNER_PID, *PMIB_UDP6ROW_OWNER_PID;

    typedef struct _MIB_UDP6TABLE_OWNER_PID
    {
        DWORD                   dwNumEntries;
        MIB_UDP6ROW_OWNER_PID   table[ANY_SIZE];
    } MIB_UDP6TABLE_OWNER_PID, *PMIB_UDP6TABLE_OWNER_PID;

    typedef enum _TCP_TABLE_CLASS {
        TCP_TABLE_BASIC_LISTENER,
        TCP_TABLE_BASIC_CONNECTIONS,
        TCP_TABLE_BASIC_ALL,
        TCP_TABLE_OWNER_PID_LISTENER,
        TCP_TABLE_OWNER_PID_CONNECTIONS,
        TCP_TABLE_OWNER_PID_ALL,
        TCP_TABLE_OWNER_MODULE_LISTENER,
        TCP_TABLE_OWNER_MODULE_CONNECTIONS,
        TCP_TABLE_OWNER_MODULE_ALL
    } TCP_TABLE_CLASS, *PTCP_TABLE_CLASS;

    typedef enum _UDP_TABLE_CLASS {
        UDP_TABLE_BASIC,
        UDP_TABLE_OWNER_PID,
        UDP_TABLE_OWNER_MODULE
    } UDP_TABLE_CLASS, *PUDP_TABLE_CLASS;


    typedef enum {
        MIB_TCP_STATE_CLOSED     =  1,
        MIB_TCP_STATE_LISTEN     =  2,
        MIB_TCP_STATE_SYN_SENT   =  3,
        MIB_TCP_STATE_SYN_RCVD   =  4,
        MIB_TCP_STATE_ESTAB      =  5,
        MIB_TCP_STATE_FIN_WAIT1  =  6,
        MIB_TCP_STATE_FIN_WAIT2  =  7,
        MIB_TCP_STATE_CLOSE_WAIT =  8,
        MIB_TCP_STATE_CLOSING    =  9,
        MIB_TCP_STATE_LAST_ACK   = 10,
        MIB_TCP_STATE_TIME_WAIT  = 11,
        MIB_TCP_STATE_DELETE_TCB = 12,
    } MIB_TCP_STATE;

#endif

typedef struct _MIB_TCPROW_EX
{
    DWORD dwState;
    DWORD dwLocalAddr;
    DWORD dwLocalPort;
    DWORD dwRemoteAddr;
    DWORD dwRemotePort;
    DWORD dwProcessId;
} MIB_TCPROW_EX, *PMIB_TCPROW_EX;

typedef struct _MIB_TCPTABLE_EX
{
    DWORD dwNumEntries;
    MIB_TCPROW_EX table[ANY_SIZE];
} MIB_TCPTABLE_EX, *PMIB_TCPTABLE_EX;

typedef struct _MIB_TCP6ROW_EX {
    UCHAR ucLocalAddr[16];
    DWORD dwLocalScopeId;
    DWORD dwLocalPort;
    UCHAR ucRemoteAddr[16];
    DWORD dwRemoteScopeId;
    DWORD dwRemotePort;
    DWORD dwState;
    DWORD dwProcessId;
} MIB_TCP6ROW_EX, *PMIB_TCP6ROW_EX;

typedef struct _MIB_TCP6TABLE_EX {
    DWORD dwNumEntries;
    MIB_TCP6ROW_EX table[ANY_SIZE];
} MIB_TCP6TABLE_EX, *PMIB_TCP6TABLE_EX;

typedef struct _MIB_UDPROW_EX
{
    DWORD dwLocalAddr;
    DWORD dwLocalPort;
    DWORD dwProcessId;
} MIB_UDPROW_EX, *PMIB_UDPROW_EX;

typedef struct _MIB_UDPTABLE_EX
{
    DWORD dwNumEntries;
    MIB_UDPROW_EX table[ANY_SIZE];
} MIB_UDPTABLE_EX, *PMIB_UDPTABLE_EX;

typedef struct _MIB_UDP6ROW_EX {
    UCHAR ucLocalAddr[16];
    DWORD dwLocalScopeId;
    DWORD dwLocalPort;
    DWORD dwProcessId;
} MIB_UDP6ROW_EX, *PMIB_UDP6ROW_EX;

typedef struct _MIB_UDP6TABLE_EX {
    DWORD dwNumEntries;
    MIB_UDP6ROW_EX table[ANY_SIZE];
} MIB_UDP6TABLE_EX,  *PMIB_UDP6TABLE_EX;

typedef DWORD (WINAPI *GetExtendedTcpTable_t)(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, TCP_TABLE_CLASS TableClass, ULONG Reserved);
typedef DWORD (WINAPI *GetExtendedUdpTable_t)(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, UDP_TABLE_CLASS TableClass, ULONG Reserved);
typedef DWORD (WINAPI *AllocateAndGetTcpExTableFromStack_t)(PVOID *ppTcpTable, BOOL bOrder, HANDLE hHeap, DWORD dwFlags, DWORD dwFamily);
typedef DWORD (WINAPI *AllocateAndGetUdpExTableFromStack_t)(PVOID *ppUDPTable, BOOL bOrder, HANDLE hHeap, DWORD dwFlags, DWORD dwFamily);
int NetStat();
int NetStatEx();
BOOL IsVista();

int main(int argc, char **argv)
{
    return ( IsVista() ) ? NetStatEx() : NetStat();    
}

BOOL IsVista()
{
    OSVERSIONINFO osver;

    osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
    
    if ( GetVersionEx (&osver) )
    {
        if ( osver.dwPlatformId == VER_PLATFORM_WIN32_NT && (osver.dwMajorVersion >= 6 ) )
            return TRUE;
    }

    return FALSE;
}

int NetStatEx()
{
    DWORD i = 0, dwRet = 0;
    DWORD dwTcpSize = 0, dwTcp6Size = 0;
    DWORD dwUdpSize = 0, dwUdp6Size = 0;
    
    MIB_TCPTABLE_OWNER_PID  *pTcp  = NULL;
    MIB_TCP6TABLE_OWNER_PID *pTcp6 = NULL;
    MIB_UDPTABLE_OWNER_PID  *pUdp  = NULL;
    MIB_UDP6TABLE_OWNER_PID *pUdp6 = NULL;

    GetExtendedTcpTable_t GetExtendedTcpTable;
    GetExtendedUdpTable_t GetExtendedUdpTable;

    HMODULE hDLL = NULL;
    
    if ( (hDLL = LoadLibrary("Iphlpapi.dll")) == NULL )
    {
        printf("fail to LoadLibrary 'Iphlpapi.dll'\n");
        return -1;
    }

    GetExtendedTcpTable = (GetExtendedTcpTable_t)GetProcAddress(hDLL, "GetExtendedTcpTable");
    GetExtendedUdpTable = (GetExtendedUdpTable_t)GetProcAddress(hDLL, "GetExtendedUdpTable");

    dwRet = GetExtendedTcpTable(NULL, &dwTcpSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
    dwRet = GetExtendedTcpTable(NULL, &dwTcp6Size, TRUE, AF_INET6, TCP_TABLE_OWNER_PID_ALL, 0);
    
    dwRet = GetExtendedUdpTable(NULL, &dwUdpSize, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0);
    dwRet = GetExtendedUdpTable(NULL, &dwUdp6Size, TRUE, AF_INET6, UDP_TABLE_OWNER_PID, 0);
        
    pTcp  = (MIB_TCPTABLE_OWNER_PID  *)malloc(dwTcpSize);
    pTcp6 = (MIB_TCP6TABLE_OWNER_PID *)malloc(dwTcp6Size);
    pUdp  = (MIB_UDPTABLE_OWNER_PID  *)malloc(dwUdpSize);
    pUdp6 = (MIB_UDP6TABLE_OWNER_PID *)malloc(dwUdp6Size);

    dwRet = GetExtendedTcpTable(pTcp, &dwTcpSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
    dwRet = GetExtendedTcpTable(pTcp6, &dwTcp6Size, TRUE, AF_INET6, TCP_TABLE_OWNER_PID_ALL, 0);
    dwRet = GetExtendedUdpTable(pUdp, &dwUdpSize, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0);
    dwRet = GetExtendedUdpTable(pUdp6, &dwUdp6Size, TRUE, AF_INET6, UDP_TABLE_OWNER_PID, 0);

    for ( i = 0; i < pTcp->dwNumEntries; i++ )
    {
        printf("IPv4 TCP Port %-10d ", ntohs( (u_short)pTcp->table[i].dwLocalPort));
        printf("Owner process id %d\n",  pTcp->table[i].dwOwningPid);
    }

    for ( i = 0; i < pTcp6->dwNumEntries; i++ )
    {
        printf("IPv6 TCP Port %-10d ", ntohs( (u_short)pTcp6->table[i].dwLocalPort));
        printf("Owner process id %d\n",  pTcp6->table[i].dwOwningPid);
    }

    for ( i = 0; i < pUdp->dwNumEntries; i++ )
    {
        printf("IPv4 UDP Port %-10d ", ntohs( (u_short)pUdp->table[i].dwLocalPort));
        printf("Owner process id %d\n",  pUdp->table[i].dwOwningPid);
    }

    for ( i = 0; i < pUdp6->dwNumEntries; i++ )
    {
        printf("IPv6 UDP Port %-10d ", ntohs( (u_short)pUdp6->table[i].dwLocalPort));
        printf("Owner process id %d\n",  pUdp6->table[i].dwOwningPid);
    }

    if ( pTcp )
        free(pTcp);

    if ( pTcp6 )
        free(pTcp6);

    if ( pUdp )
        free(pUdp);

    if ( pUdp6 )
        free(pUdp6);

    FreeLibrary(hDLL);

    return 0;   
}

int NetStat()
{
    DWORD i = 0;
    HMODULE hDLL = NULL;
    HANDLE hHeap = NULL;
    PMIB_TCPTABLE_EX pTcp = NULL;
    PMIB_UDPTABLE_EX pUdp = NULL;
    PMIB_TCP6TABLE_EX pTcp6 = NULL;
    PMIB_UDP6TABLE_EX pUdp6 = NULL;
        
    AllocateAndGetTcpExTableFromStack_t AllocateAndGetTcpExTableFromStack = NULL;
    AllocateAndGetUdpExTableFromStack_t AllocateAndGetUdpExTableFromStack = NULL;

    hHeap = GetProcessHeap();

    if ( (hDLL = LoadLibrary("iphlpapi.dll")) == NULL )
        return -1;

    if ( (AllocateAndGetTcpExTableFromStack = (AllocateAndGetTcpExTableFromStack_t)GetProcAddress(hDLL, "AllocateAndGetTcpExTableFromStack")) == NULL )
        return -1;

    if ( (AllocateAndGetUdpExTableFromStack = (AllocateAndGetUdpExTableFromStack_t)GetProcAddress(hDLL,"AllocateAndGetUdpExTableFromStack")) == NULL )
        return -1;

    if ( AllocateAndGetTcpExTableFromStack((PVOID *)&pTcp, TRUE, hHeap, 0, AF_INET) == NO_ERROR )
    {
        for ( i = 0; i < pTcp->dwNumEntries; i++ )
        {
            printf("IPv4 TCP Port %-10d ", ntohs( (u_short)pTcp->table[i].dwLocalPort));
            printf("Owner process id %d\n",  pTcp->table[i].dwProcessId);
        }
    }

    if ( AllocateAndGetTcpExTableFromStack((PVOID *)&pTcp6, TRUE, hHeap, 0, AF_INET6) == NO_ERROR )
    {
        for ( i = 0; i < pTcp6->dwNumEntries; i++ )
        {
            printf("IPv6 TCP Port %-10d ", ntohs( (u_short)pTcp6->table[i].dwLocalPort));
            printf("Owner process id %d\n",  pTcp6->table[i].dwProcessId);
        }
    }

    if ( AllocateAndGetUdpExTableFromStack((PVOID *)&pUdp, TRUE, hHeap, 0, AF_INET) == NO_ERROR )
    {
        for ( i = 0; i < pUdp->dwNumEntries; i++ )
        {
            printf("IPv4 UDP Port %-10d ", ntohs( (u_short)pUdp->table[i].dwLocalPort));
            printf("Owner process id %d\n",  pUdp->table[i].dwProcessId);
        }
    }

    if ( AllocateAndGetUdpExTableFromStack((PVOID *)&pUdp6, TRUE, hHeap, 0, AF_INET6) == NO_ERROR )
    {
        for ( i = 0; i < pUdp6->dwNumEntries; i++ )
        {
            printf("IPv6 UDP Port %-10d ", ntohs( (u_short)pUdp6->table[i].dwLocalPort));
            printf("Owner process id %d\n",  pUdp6->table[i].dwProcessId);
        }
    }
        
    if ( pTcp )
        HeapFree(hHeap, 0, pTcp);
    
    if ( pUdp )
        HeapFree(hHeap, 0, pUdp);
    
    if ( pTcp6 )
        HeapFree(hHeap, 0, pTcp6);
    
    if ( pUdp6 )
        HeapFree(hHeap, 0, pUdp6);
    
    FreeLibrary(hDLL);
    
    return 0;
}

※ 설명의 편의상 예외처리를 거의 하지 않았으니, 가져다 쓰실때에는 꼭 예외처리 추가하는 센스 !!!  잊지마세요~~

블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

Visual Studio관련 다운로드
(서비스팩,재배포,Platform SDK,Windows SDK,DirectX SDK)


Microsoft Download 링크입니다.

아래 링크는 자주 바뀌므로 링크가 없을시는 이름으로 검색하시면 됩니다.

64-bit 모드는 x86페이지를 따라가서 받자. 페이지가 너무 길어짐;;

64-bit 모드(IA64, X64)에 관해서


 

Microsoft Windows SDK Blog

Windows SDK MSDN Developer Center
Windows SDK -> Platform SDK + .Net로 이름이 변경됨.

DirectX Developer Center


※ ATL관련 긴급보안 업데이트 관련 내용은 따로 정리했음. (2003~2008 sp1까지 해당됨)
Visual Studio ATL Security Update

VC 9.0(VS2008)

설치 순서 (SP1을 SDK보다 먼저 깔면 CRT라이브러리가 최신버젼으로 적용안됨)
SDK -> SP1 -> ATL

Windows® SDK for Windows Server® 2008 and .NET Framework version 3.5
- Windows Server® 2008와 .Net3.5를 위한 최신 버젼(2009년 4월 30일 기준으로 window7용 sdk가 나왔지만 아직은 beta)

Microsoft Visual Studio 2008 서비스 팩 1(iso)

MSDN Library for Visual Studio 2008 SP1 (2008년 12월 버전)

Microsoft Visual C++ 2008 SP1 재배포(Redistributable) 가능 패키지(x86)

Windows® SDK for Windows Server® 2008 and .NET Framework version 3.5(2008-05-02) 설치목록


VC 8.0(VS2005)

Windows® Server 2003 R2 Platform SDK Full Download
- 이버젼 이후로 Windows SDK로 변경, 2003(마지막),2005지원

Microsoft® Windows® Software Development Kit Update for Windows Vista - 2005 sp1이상

Microsoft® Visual Studio® 2005 Team Suite 서비스 팩 1


Microsoft Visual C++ 2005 SP1 재배포(Redistributable) 가능 패키지(x86) - 2.6MB

Windows® Server 2003 R2 Platform SDK(2006-03-15) 설치목록


2005제거시 맨마지막에 뜨는 정리하라는 메세지!!



VC 6

Platform SDK february 2003
VC6 지원 마지막 버젼

DirectX SDK : DirectX 9.0 SDK Update - (Summer 2004)
VC6 지원 마지막 버젼

Visual Studio 6.0 Service Pack 6

Visual Studio 6.0 Service Pack 5 - Processor Pack을 깔기위해선 서비스팩 5가 필요함

Processor Pack -  인텔의 MMX 함수를 사용하기 위해 꼭 깔아야 한다. 코덱등의 작업을 하려면 필수.

Microsoft Visual C++ 6 배포

Platform SDK february 2003 설치목록


참고
최근 Microsoft® Windows® Software Development Kit (MS Windows SDK) 릴리즈 기간에 대한 상념

블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,


알툴바를 아시는지요? Internet Explorer 로 인터넷을 서핑할 때 마우스 오른쪽 버튼을 이용하여 키보드 사용을 최소화할 수 있도록 도와주는 툴입니다. 마우스의 동작을 인식하는 일명 Gesture 기능이지요.
 
이제 Visual Studio 에서도 이 기능을 사용할 수 있습니다.
VSGesture 는 Visual Studio 에서도 마우스의 동작을 인식하여 명령을 할 수 있습니다.

 
VSGesture v1.0
 


다운로드(Download)

이 링크에서 다운로드 받으십시오.

VSGesture 는 Visual Studio Gallary 사이트에서도 찾을 수 있습니다.
 

 
사용방법 : 코드 에디터에서 마우스 오른쪽 버튼을 클릭하고 동작을 그린다!
 
[그림1] VSGesture 실행 화면
 
설치 환경
l Windows Vista 이상
l .NET Framework 3.5 SP1
l Visual Studio 2008 / 2005
 
주요 기능
l 문서 이동
l 빌드
l 디버그
l 문서 제어
 
 
잠깐! VSGesture 는 Windows Vista 이상을 지원합니다.
 
Windows XP 또는 Windows Server 2003 사용자는 아래의 구성 요소를 다운로드 받아야 합니다. 단, 반드시 순서대로 설치하셔야 합니다.
 
Microsoft Windows XP Tablet PC Edition Software Development Kit 1.7
 
Microsoft Windows XP Tablet PC Edition 2005 Recognizer Pack
 
 
 
마우스 동작 사용법
 


 
편리한 VSGesture Visual Studio 와 함께 즐프하세요.


 

블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

배포시에는 Dependency Walker(depends.exe)와 같은 도구를 사용하여 종속 DLL의 목록을 확인한다. 또한 2005이상의 VS(Visual Studio)는 manifest를 꼭 확인해서 사용한 dll과 버전을 확인해야한다.

VC++ Library
그림 1(VS2005 기준)

그림은 VS2005를 기준으로 하고 있지만 다른 버젼도 위와 같은 규칙으로 명명되고 있다. xx는 각각의 버전을 나타내며 플랫폼 별로 x86,ia64,x64용이 따로 있다. u는 Unicode버전을 나타내고 m은 managed code를 사용했을때 사용되며 배포시 .NET Framework이 필요하다. 배포폴더에 manifest가 존재하면 같이 배포한다.

참고
Visual C++ Libraries as Shared Side-by-Side Assemblies - MSDN

접기

64-bit 모드(IA64, X64)에 관해서

X86: 우리가 흔히 알고 있는 IA32 명령어 기반의 프로세서를 말한다.

IA64(EPIC instruction set): 인텔 Itanium 프로세서부터 채용된 새로운 명령어 집합. 기존 IA32와 호환이 되지 않는다. EPIC(Explicitly Parallel Instruction Computing) instruction set을 가지며, 많은 차이점이 있겠지만, predicated instructions을 지원한다는 것과 최소 6개의 floating point unit은 기억할만하다.

X64: AMD Opteron 프로세서부터 채용되었고, AMD64, Intel64(EM64T)으로 소개되었지만, 지금은 X64로 보통 부른다. IA32를 64-bit을 지원하기위해 확장한 것으로, IA32와 완전한 호환을 가지는 Compatibity mode와 64-bit mode를 지원한다. 우리가 흔히 말하는 64-bit 모드이다. 

- 64-bit mode에서는 명령어에 8-bit REX prefix를 붙여서, 64-bit 레지스터를 사용할 수 있다. 또한, 64-bit mode에서는 레지스터 개수도 기존의 8개에서 16개로 다음과 같이 늘어났다.
   - Long mode - Compatibility mode: eax, edx, exc, ebx, esi, edi, esp, ebp
   - Long mode - 64-bit mode: rax, rdx, rxc, rbx, rsi, rdi, rsp, rbp, r8,r9,r10,r11,r12,r13,r14,r15

- AMD64에서는 Operating mode로서 총 5개가 지원된다.
   - Long mode - Compatibility mode
   - Long mode - 64-bit mode
   - Legacy mode - Protected mode
   - Legacy mode - Virtual 8086 mode
   - Legacy mode - Real mode

- AMD64의 어드레스는 레지스터 값은 64bit으로 부호확장되어 보이며, 현재는 다음과 같은 범위를 가진다.
 - physical address: 1TB (40-bit)
 - virtual address: 256TB (48-bit) : 부호확장이 되었으므로, 유효한 virtual address는 다음 두 영역으로 된다.
   - 0x0 ~ 0x00007FFF_FFFFFFFF
   - 0xFFFF8000_00000000 ~ 0xFFFFFFFF_FFFFFFFF

참고
http://blog.naver.com/purnnam1/60065549452

접기


컴파일러와 라이브러리의 버젼을 나타내는 매크로

Predefined Macros - MSDN

_MSC_VER(MS 컴파일러)

  Visual Studio 4.0  1000
  Visual Studio 5.0  1100
  Visual Studio 6.0  1200
  Visual Studio .NET 2002  1300
  Visual Studio .NET 2003  1310
  Visual Studio 2005  1400
  Visual Studio 2008  1500

_MFC_VER(MFC 버젼)

 Visual Studio 6.0   0x0600
 Visual Studio .NET 2002   0x0700
 Visual Studio .NET 2003  0x0710
 Visual Studio 2005  0x0800
 Visual Studio 2008  0x0900

_ATL_VER(ATL 버젼)

 Visual Studio 6.0   0x0300
 Visual Studio .NET 2002   0x0700
 Visual Studio .NET 2003  0x0710
 Visual Studio 2005  0x0800
 Visual Studio 2008  0x0900


VC 6 이하(~ VS6)
VC6관련 DLL은 98이후부터는 운영체제에 포함되어 있다. 그러므로 현재는 배포시에 거의 문제될게 없다.

참고
ActiveX 배포를 위한 cab파일(MS) - inf파일에 링크를 추가해준다.
Vcredist.exe로 Visual C++ 응용 프로그램용 최신 런타임 구성 요소가 설치된다 - MSDN고객지원

VC 7.1(VS 2003)
VC7.1관련 DLL은 최신 운영체제라고 해서 더는 기본 내장을 해주지않기 때문에 응용 프로그램이 알아서 자기 디렉터리나 윈도우 시스템 디렉터리에다 구비해야 한다.



VC 8이후(VS 2005~)

Side by Side Asembly
2005부터는 side by side asembly라는 기술이 도입되어 VC관련 라이브러리들이 Windows 디렉토리 밑에 WinSxS (Windows Side-by-Side)라는 공유 폴더(native assembly cache)로 관리된다. side by side asembly는 DLL 충돌문제를 해결해서 각각의 어플리케이션에게 독립적인 DLL환경을 제공하기 위한것으로 여러버젼의 DLL들이 등록될수 있다. 복잡한 이과정을 간단하게 해결하는 방법으로 VC8부터는 재배포 패키지(Redistributable Package)라는 배포용 설치파일이 도입되어 공용 라이브러리를 자동으로 설치/등록해준다. 또한 프로젝트에서 자동 생성해주는 Manifest Flie에 사용된 DLL과 버전이 자동으로 입력되니 배포시는 꼭 확인하도록 한다.
프로그래머나 사용자입장에선 관련 DLL을 포함만 하면 되는 기존 작업과 달리 설치파일이 하나 더생겼으니 귀찮은 작업이지만 최신 운영체제의 기본 관리 방법이기도 하고 .Net의 기술과도 무관하지 않으니 지금 정리하도록 하자.


최신 라이브러리를 Manifest에 기술하기(VC9)
배포방법을 알아보기 전에 알아두어야 할사항이 있다. VC9는 VC8과 달리 sp1같은 최신 라이브러리를 개발자PC에 설치했다고 해도 프로젝트가 최신라이브러리를 사용한다고 명시해주지 않으면 기존라이브러리를 기본으로 사용하므로 주의해야한다. 이것은 개발자가 sp1을 설치했어도 프로젝트는 기존 DLL버전을 사용하므로 배포시 sp1용 재배포 패키지를 사용하면 제대로 실행될 수 없음을 나타낸다. 방법은 아래와 같다.

'_BIND_TO_CURRENT_VCLIBS_VERSION'를 프로젝트 설정에서 선언해준다.
-> stdafx.h의 상단에 #define으로 입력해도 일반적인 프로젝트에선 상관없지만 프리컴파일드 헤더를 사용안하거나 외부라이브러리가 프로젝트에 미리 세팅되었을 경우 두개의 버전을 중복 사용하는 경우가 발생할 수 있으므로 프로젝트 설정에서 선언하길 권장한다. 이값은 CRT,MFC,ATL,OPENMP 4개의 '_BIND_TO_CURRENT...' 선언을 다 쓰겠다고 선언하는것이고 _BIND_TO_CURRENT_VCLIBS_VERSION의 기본값은 0으로 세팅되어있다.

접기

2008에서 MFC프로젝트 생성시 자동으로 생성해주는 Manifest file이다. Manifest File의 종류는 External(외부)와 Internal(내부)가 있는데 VC프로젝트 기본설정으로 컴파일시 Internal로 Exe파일에 자동으로 포함된다. 위치는 파일의 거의 마지막 부분이고 일반적인 텍스트로 아래와 같이 보이므로 메모장 등으로 확인해보자.
01.<P style="MARGIN: 0cm 0cm 0pt" class=MsoNormal>
02.<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
03.  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
04.    <security>
05.      <requestedPrivileges>
06.        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
07.      </requestedPrivileges>
08.    </security>
09.  </trustInfo>
10.  <dependency>
11.    <dependentAssembly>
12.      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
13.    </dependentAssembly>
14.  </dependency>
15.  <dependency>
16.    <dependentAssembly>
17.      <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
18.    </dependentAssembly>
19.  </dependency>
20.  <dependency>
21.    <dependentAssembly>
22.      <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
23.    </dependentAssembly>
24.  </dependency>
25.</assembly>
26.</P>
2008의 기본 Dll버전은 9.0.21022.8이고 sp1은 9.0.30729.1, ATL 관련 보안업데이트시 9.0.30729.4148버전을 사용한다.

참고

외부 Manifest와 내부 Manifest의 적용 순서

접기


참고

응용 프로그램 재배포 및 특정 라이브러리에 바인딩 - MSDN

최신 라이브러리를 메니페스트에 기술하기


배포방법
그림1과 참고에 MSDN링크가 2005의 공용DLL 목록과 설명이다. side by side asembly로 인해 배포문제가 좀 복잡해져서 depends 만을 확인해서 관련 DLL을 포함한다고 제대로 실행된다는 보장을 받을 수 없게되었다. 일반적인 방법과 재배포 패키지를 사용하는 방법을 알아보자.

1. 정적 라이브러리(Static Library)를 사용한다.
실행파일이 커지긴 하나 제일 간단하다. MFC 라이브러리를 사용시는 MFC라이브러리를 정적으로 포함하면 CRT도 자동으로 /MT로 변경된다. 용량은 기본 MFC 다이얼로그 프로젝트가 52k정도에서 308k 정도로 커진다.
ATL과 OPENMP까지 사용한다면 웹에서 배포되는 ActiveX 같은 상황이면 용량때문에 고민해봐야할 문제이고 정적라이브러리도 동적라이브러리와 똑같다고는 하지만 몇가지 버그가 있으므로 주의하자.

참고
MFC Static으로 소켓사용시..

2. Manifest를 참조해서 기본 DLL을 배포한다.(Private Assembly)
배포방법이 바뀌었다곤 하나 관련 DLL을 포함해서 배포할수도 있다. VS의 설치폴더에 있는 공용DLL(Private Assembly)을 같이 배포하면 된다. 우선 Manifest로 사용한 DLL을 확인한후 "..\Microsoft Visual Studio X\VC\redist\"에서 관련 DLL(그림1참고)을 프로젝트 폴더에 포함한다. 이방법도 쉬운편이긴 하나 3MB정도의 크기인 재배포 패키지에 비하면 사용하는 라이브러리가 많을 수록 용량이 너무 큰편이다.(기본 CRT와 MFC라이브러리만 4.76MB - 2008sp1 기준)

3. 인스톨쉴드(Install Shield), 설치 프로젝트를 이용해서 재배포 패키지가 자동으로 설치되게 한다.
 -> 모든 프로젝트를 이렇게 만들긴 좀 귀찮다;;

4. .Net Framework(최신)를 설치한다.
.Net Framework를 설치하면 CRT관련 DLL만 같이 설치된다.(fx 3.5설치시 8.0과 9.0이 같이 설치됨)
managed로 컴파일했다면 .Net Framework는 필수이므로 고민할 문제가 아니지만 용량이 100메가도 훨씬 넘는다..;;

5. 재배포 패키지 - 아래에서 따로 설명한다.

위 방법 외에도 몇가지가 더 있으며 아래링크를 참조하기 바란다.
RedistributingVisualCppRunTimeLibrary
Bootstrapper for the VC++ 2005 Redists (with MSI 3.1) - codeproject

재배포 패키지(Redistributable Package)
재배포 패키지는 Windows Installer 3.1을 필요로 하는 인스톨 파일이다. 한번 실행하기만 하면 자동으로 설치되지만 사용자 입장에선 불편한 사항이다. 하지만 Windows Installer의 Command line을 이용해서 몰래설치하는 방법이 있다. 이를 이용해서 런처형식의 프로그램을 만들면 Windows Installer 3.1의 설치유무와 재배포 패키지 자동 설치를 하고 프로그램을 실행하게 할 수 있다. 좀더 범용적으로 사용하면 파일로 설치필요 설정값을 받아와서 COM관련 등록이나 웹배포시 ActiveX등록등을 자동으로 하게 만들수도 있다. 관련 소스가 정리되는 대로 블로그에 올리도록 하고 우선 VC6으로 재배포 패키지의 설치유무와 자동 실행하기 위한 코드를 설명하겠다.

1) 재배포 패키지 설치 유무 확인
재배포 패키지는 설치폴더에서 받거나(..\Microsoft Visual Studio X\SDK\v2.0\BootStrapper\Packages\vcredist_x86) 아래 링크를 통해 MS의 다운로드에서 받는다.

2-1) 일반 적인 인스톨러 사용처럼 추가/제거 목록에 표시되므로 레지스트리 값으로 확인할 수 있다.
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ProductCode"

2-2) MsiQueryProductState API를 이용해서 확인한다.
리턴값으로 INSTALLSTATE_DEFAULT인지만 확인하면 설치유무를 판단할 수 있다.

위 2개의 방법에서 모두 필요한 ProductCode는 아래와 같다.

Visual C++ 2005 runtime files

Visual C++ 2005 SP1 runtime files

Visual C++ 2008 runtime files

Visual C++ 2008 SP1 runtime files

위코드는 영문 버전이고 한글버전은 다르고 설치시 중복될수 있다. ProductCode와 추가/제거에 표시되는 이름외에 다른점은 없다. 참고로 2008 sp1 x86 한글버전은 {887868A2-D6DE-3255-AA92-AA0B5A59B874}이다.
Window7에서도 테스트 했음.

참고
How to detect the presence of the VC 8.0 runtime redistributable package
How to detect the presence of the Visual C++ 9.0 runtime redistributable package
NSIS로 VC8.0 Redistributables 체크방법
MsiQueryProductState를 통한 VC 2005 Redistribute 라이브러리 설치체크 방법


2) 재배포 패키지 몰래 설치하기(Command Line)
명령행으로 실행시 Windows Installer 로 만들어진 패키지는 /?로 명령어 종류를 볼수 잇다.

접기

Windows Installer V3.0.1.4001.5512 기준으로 캡쳐한화면이다.


접기


VS2005
VC2005의 경우는 재배포 패키지가 VS기본 폴더에 존재하는 설치파일과 웹에서 받은 파일이 좀 다른데 웹에서 받은 재배포 패키지의 경우 압축이 한번더 되어있어서 인자값 설정 방법이 다르다. 또한 압축이 몇번에 걸쳐 되어있으므로 한글로 계정이 되어있어 한글 경로가 있을 경우 잘 설치가 안될수도 있다. 필자는 2008을 사용하므로 2005에 대한 사항은 관련 링크로 정확한 정보를 얻자.
How to perform a silent install of the Visual C++ 8.0 runtime files (vcredist) packages
- VS기본 폴더에 포함된 재배포 패키지 설치
VC 8.0 런타임 (vcredist) 패키지 몰래 인스톨하기 - 웹에서 받은 재배포 패키지 설치(번역)
Visual C++ 2005 재배포 패키지가 설치안될때



VS2008
2008에서는
<full path>\vcredist_x86.exe /qb
<full path>\vcredist_x86.exe /qb!
<full path>\vcredist_x86.exe /q   -> 화면에 전혀 보이지 않음
위 3가지 방법중 선택해서 사용하면 되며 Vista이상의 경우는 /q로 설정해도 UAC가 보이므로 필자는 /qb!를 사용한다. 직접 사용해보고 판단하자.

참고
How to perform a silent install of the Visual C++ 2008 redistributable packages

99%'s Code
위 재배포 패키지 몰래설치하기 코드를 간단하게 정리했음.

1. 설치유무 판단후 재배포 패키지를 설치하고 원하는 파일을 실행한다.
01. // 2008 sp1
02.    CString csProduct = "{887868A2-D6DE-3255-AA92-AA0B5A59B874}";   
03.//{9A25302D-30C0-39D9-BD6F-21E6EC160475}
04.  
05.    INSTALLSTATE t = MsiQueryProductState(csProduct);
06.    if(INSTALLSTATE_DEFAULT != t)
07.    {
08.        AfxMessageBox("재배포 패키지를 설치하겠습니다.");
09. //    WinExec("vcredist_sp1_x86.exe /q",SW_SHOW);
10.        WinExec("vcredist_sp1_x86.exe /qb!",SW_SHOW);
11.        AfxMessageBox("설치 완료"); 
12. // xp에선 설치완료후 정확하게 뜨지만 Windows7에선 완료되지 않았는데 뜬다.
13.    }
14.    else
15.        AfxMessageBox("이미 설치됨");
16.     
17.    // 아래 레지스트리값의 유무로 판단할수도 있다.(win7에서도 똑같다.)
18.    //HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{887868A2-D6DE-3255-AA92-AA0B5A59B874}
19.     
20.    while(INSTALLSTATE_DEFAULT != MsiQueryProductState(csProduct))
21.        Sleep(30);
22.    WinExec("test.exe",SW_SHOW);    // 원하는 프로그램 실행
2. 제거
    WinExec("vcredist_sp1_x86.exe /qu",SW_SHOW);
    AfxMessageBox("제거 완료");


 

블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

STL 컨테이너는 각각 자신만의 특징을 가지고 있습니다. 각 컨테이너의 특징은 성능('시간 복잡도' '공간 복잡도')
STL
여러 요소에 영향을 주기 때문에 각 컨테이너의 특징을 이해하는 것은 상당히 중요합니다. 그래야 자신의 프로그램에 맞는 적절한 컨테이너를 선택하여 사용할 수 있습니다
.

vector
의 주요 특징은 앞장에서 배운 것처럼 '시퀀스 컨테이너'이면서 '연속 메모리 기반 컨테이너'입니다
.
또 컨테이너에 데이터가 삽입될수록 메모리가 자라나게 됩니다. 연속 메모리 기반이므로 메모리가 자라나면

기존 메모리를 삭제하고 새로운 메모리를 재할당하여 사용합니다.

v.size() = 인덱스 사이즈
v.clear() =
초기화
v.capacity() =
할당된 메모리 공간 크기 보기
v.empty() =
비어있는지 확인 true/false
v.push_back(data) =
끝에 자료 추가

v.pop_back() =
끝에꺼 삭제
v.erase( v.begin() + 3) = 3
번째 내용 삭제
v.insert( v.begin()+0, "aa") = 0
번째 aa추가
v.reserve( 10 ) = capacity(
공간 크기 설정)
v.begin() =
시작위치
iterator
v.end() =
끝위치
iterator
v.swap( vector) = 
벡터간 SWAP

 

전형적 일반 벡터 생성하기
vector< Templete > v; // v
란 이름으로 < > 타입의 벡터 리스트를 생성하기


생성자를 이용한 메모리공간과 크기 확보하여 초기화 생성하기
vector<int> v(10);
v.size() // 10개의 빈공간이 생성되잇다.


간단한 예제

#include<iostream>
#include<vector>
using namespace std;

int main()
{
        vector<
int> i_list; //
벡터 변수 선언
        i_list.push_back(10);//
끝에 추가
        i_list.push_back(20);
        i_list.push_back(
30);

       
for(int i=0;i<i_list.size();i++)
               
if( !i_list.empty() )
                        cout <<
"size: " << i_list.capacity() << " content: " << i_list[i] << endl;

        i_list.erase(i_list.begin()+
1); // 1
번인덱스 삭제
        i_list.insert(i_list.begin()+1, 20); // 1
번째 인덱스에 자료 추가

        i_list.pop_back(); //
끝에꺼 삭제

        i_list.clear(); //
완전삭제
        return 0;
}


반복자를 이용한 벡터 접근하기

#include<iostream>
#include<vector>
using namespace std;

int main()
{
    vector<
int> v;

   
for(int i = 0 ; i < 10 ; i++)
        v.push_back(i);

    vector<
int>::iterator iter;

   
for( iter = v.begin() ; iter != v.end() ; iter++)
        cout << *iter << endl;

    cout << *iter << endl;
    cout << *iter+
1 << endl;
    cout << *iter+
2 << endl;
   
return 0;
}

#include<iostream>
#include<vector>
using namespace std;

int main()
{
    vector<int> v;

    for(int i = 0 ; i < 10 ; i++)
        v.push_back(i);

    vector<int>::iterator iter;

    for( iter = v.begin() ; iter != v.end() ; iter++)
        cout << *iter << endl;

    cout << *iter << endl;
    cout << *iter+1 << endl;
    cout << *iter+2 << endl;
    return 0;
}

 

블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,
#pragma comment(lib,"ws2_32.lib")
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <process.h>
#define BUFSIZE 1024

int main(int argc, char** argv){
    WSADATA wsaData;
    SOCKET hServSock;
    SOCKET hClntSock;

    HANDLE hThread;
    DWORD dwThreadID;

    SOCKADDR_IN servAddr;
    SOCKADDR_IN clntAddr;
    int clntAddrSize;

    if(argc != 2){
        printf("Usage: %s <port> \n", argv[0]);
        exit(1);
    }
    if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHandling("WSAStartup() error!");

    hServSock = socket(PF_INET, SOCK_STREAM, 0);
    if(hServSock == INVALID_SOCKET)
        ErrorHandling("socket() error");

    memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servAddr.sin_port = htons(atoi(argv[1]));

    if(bind(hServSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
        ErrorHandling("bind() error");

    if(listen(hServSock, 5) == SOCKET_ERROR)
        ErrorHandling("listen() error");

    while(1){
        clntAddrSize = sizeof(clntAddr);
        hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &clntAddrSize);
        if(hClntSock == INVALID_SOCKET)
            ErrorHandling("accept() error");

        printf("연결 요청: %s:%d \n", inet_ntoa(clntAddr.sin_addr), ntohs(clntAddr.sin_port));

        hThread = (HANDLE)_beginthreadex(NULL, 0, ClntConnect, (void*)hClntSock, 0, (unsigned int*)&dwThreadID);
        if(hThread == 0){
            puts("쓰레드 생성");
            exit(1);
        }
    }

    WSACleanup();
    return 0;
}

DWORD WINAPI ClntConnect(void* arg){
    SOCKET hClntSock = (SOCKET)arg;
    char buf[BUFSIZE];

    recv(hClntSock, buf, BUFSIZE, 0);
    send(sock, protocol, strlen(protocol), 0); 

    return 0;
}

void ErrorHandling(char* message){
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

#pragma 키워드는 컴파일러 제작 회사가 특정 플랫폼에 의존하는 기능을 확장하기위해 기능을 추가한 키워드이다.

해당 컴파일러가 지시명을 인식하지 못한다면 에러 또는 경고 메세지를 수반하지 않고서 #pragma의 지시를 무시하게  된다.

 

#pragma 옵션

  옵션

  설명

 allock_text

 

 comment

 코드 안에 특별한 주석을 기입함

 init_seg

 

 optimize

 

 auto_inline

 

 component

 

 inline_depth

 

 pack

 변수 정렬을 인위적으로 변경

 bss_seg

 

 data_seg

 다른 파일에서 데이터를 공유하고자할때

 inLine_recursion

 

 pointers_to_members

 

 check_stack

 

 function

 

 intrinsic

 

 setlocale

 

 code_seg

 

 hdrstop

 

 message

 컴파일시 메시지를 출력함

 vtordisp

 

 const_seg

 

 include_alias            

 

 once

 해당 파일이 한번만 포함

 warning

 컴파일러 경고 메시지를 만들거나 안보이게 함

 link

 실행화일에 파일을 링크

 

#pragma once

ex> #pragma once

전처리기가 이 행을 처리하려고 할 때, 이 파일은 오직 한 번 추가되어야 한다는 것을 알게 된다.

 

#pragma pack

ex>

#pragma pack(n)   //n으로 정렬방식을 바꾼다.

#pragma pack()     //Default 정렬방식을 바꾼다.

#pragma pack(push, n)  //n의로 정렬 방식을 바꾸고 기존정렬방식을 스택에 저장한다.
#pragma pack(pop)       //
스택에 저장한 정렬방식으로 다시 돌린다.

 

pack 지시자는 이 후 부터 선언되는 구조체의 정렬 방식을 지정하는 것이다. n은 컴파일러가 저장된 메모리에 데이터를 정렬하는 방법을 결정하는 byte의 크기이다.

 

ex>

#pragma pack(1)

typedef struct _TEST_STRUCT
{
    char CharValue;   
//1byte
    char CahrValue2;  //1byte
    int  IntValue;         //4byte
    char* pCharValue; //4byte
    int* pIntValue;       //4byte

} TEST_STRUCT, *PTEST_STRUCT;
#pragma pack()

 

위 구조체를 sizeof() 로 구조체의 크기를 알아보면 문제가 있음을 알 수 있다. 위 구조체의 크기는 14byte이다. 하지만 sizeof()로 크기를 알아보면 16byte로 나타나는 것을 알 수 있다. 이 떄 pack을 사용하면 빈공간 없이 14byte로 구조체가 선언된것을 알 수 있다.

 

#pragma warning

ex>

 

#pragma warning (disable:4101)                            // 경고를 무시하도록 한다.

#pragma warning (once:4101)                               // 4101경고를 한 번만 출력한다.

#pragma warning (error:4700)                                          // 경고 대신 에러를 출력한다.

#pragma warning (3:4706)                                     // 4706번 경고를 레벨 3으로 올린다.

이 지시자는 컴파일시 나오는 경고를 설정한다. 이것으로 매 컴파일 마다 나오는 경고를 없애거나 한번만 나오게 할 수있다.

제어문

설명

once : 번호

반복되는 경고를 번만 출력한다.

default : 번호

원래 설정대로 되돌린다.

disable : 번호

경고를 출력하지 않는다.

error : 번호

경고를 에러로 처리한다.

level : 번호

경고의 레벨(1~4) 변경한다.

push[,n]

모든 경고의 레벨을 저장한다. n 있을 경우 저장과 동시에 전역 경고 레벨을 n으로 변경한다.

pop

스택에 마지막으로 저장된 경고 레벨을 복원한다.

 

#pragma comment

ex>

#pragma comment(lib, "d3d8.lib")

 

이 지시자는 해당 옵션에 따라 다양한 주석문 및 문자를 코드에 추가한다.

  옵션

  설명

 lib

 코드 내에서 명시적으로 라이브러리의 링크를 지정해준다

 exestr

 기록된 string 실행파일 내부에 기록되어지며, 이것은 결코 메모리로 load되지 않는다. 다만 파일 검색 유틸리티를 사용하여 실행파일에서 string 찾아볼 수 있다.

 user

 ".OBJ" file string을 기록합니다. 하지만 linker에 의해 string은 무시되어집니다. object 파일에만 그 내용이 남게 됩니다

 

#pragma data_seg

ex>

#pragma data_seg(".mine$a")  //.mine 명으로 공유, Section 이름은 8자 또는 그 이하로 해야한다.
int g_nCount1 = 0;

#pragma data_seg(".mine$z")  //'$' 기호 전에 동일 이름인 섹션들은 한 개의 섹션으로 통합이 된다. 여기서 통합의 순서는

                                               '$'다음의 문자 정렬로 순서를 결정한다.
int g_nCount2 = 0;
#pragma data_seg()               
//Default
로 복원

 

 #pragma comment( linker, "/SECTION:.mine, RWS" )  // R:Read, W:Write, S:Shared

 

우선은 공유할 데이터(변수) Global 변수로 선언하고 #pragma data_seg 위와 같이 추가한 다음 Linker 코드를 추가하면 g_nCount1 g_nCount2데이터를 DLL 외부에서 공유할 수 있게 된다.

 

#pragma link

ex>

#pragma comment( linker, "/SECTION:.SHAREDATA, RWS" )  // R:Read, W:Write, S:Shared

 

이 지시자는 실행파일에 해당 파일을 Link 시킨다.

옵션

 설명

/ALIGN:number

Specifies the alignment of each section

/BASE:{address | @filename,key}

Sets a base address for the program

/COMMENT:["]comment["]

Inserts a comment string into header

/DEBUG

Creates debugging information

/DEBUGTYPE:CV
/DEBUGTYPE:COFF
/DEBUGTYPE:BOTH

Creates particular formats of debugging information

/DEF:filename

Passes a module-definition (.DEF) file to the linker

/DEFAULTLIB:library

Searches specified library when resolving external references

/DELAY

Controls the delayed loading of DLLs

/DELAYLOAD

Causes the delayed loading of the specified DLL

/DLL

Builds a DLL

/DRIVER[:UPONLY]

Creates a Windows NT kernel mode driver

/ENTRY:function

Sets the starting address

/EXETYPE:DYNAMIC

Builds a virtual device driver

/EXPORT

Exports a function

/FIXED[:NO]

Creates a program that can be loaded only at its preferred base address

/FORCE[:{MULTIPLE|UNRESOLVED}]

Forces link to complete in spite of unresolved or multiply defined symbols

/GPSIZE:#

Specifies the size of communal variables for MIPS and Alpha platforms

/HEAP:reserve[,commit]

Sets the size of the heap in bytes

/IMPLIB:filename

Overrides the default import library name

/INCLUDE:symbol

Forces symbol references

/INCREMENTAL:{YES|NO}

Controls incremental linking

/LARGEADDRESSAWARE

Tells the compiler that the application supports addresses larger than two gigabytes.

/LIBPATH:path

Allows the user to override the environmental library path

/LINK50COMPAT

Generates import libraries in Visual C++ Version 5.0 format

/MACHINE:{IX86|ALPHA|ARM|MIPS|MIPSR41XX|PPC|SH3|SH4}

Specifies the target platform

/MAP

Creates a map file

/MAPINFO:{EXPORTS|FIXUPS|LINES}

Includes the specified information in the map file

/MERGE:from=to

Combines sections

/NODEFAULTLIB[:library]

Ignores all (or specified) default libraries when resolving external references

/NOENTRY

Creates a resource-only DLL

/NOLOGO

Suppresses startup banner

/OPT:{REF|NOREF|ICF[,iterations]|NOICF}

Controls LINK optimizations

/ORDER:@filename

Places COMDATs into the image in a predetermined order

/OUT:filename

Specifies the output file name

/PDB:filename

Creates a program database (.PDB) file

/PDBTYPE:{con[solidate]|sept[ypes]}

Specifies where to store the Program Database (PDB) debug type information.

/PROFILE

Enables profiling (creates a mapfile)

/RELEASE

Sets the checksum in the .EXE header

/SECTION:name,attributes

Overrides the attributes of a section

/STACK:reserve[,commit]

Sets the size of the stack in bytes

/STUB:filename

Attaches an MS-DOS stub program to a Win32 program

/SUBSYSTEM:{CONSOLE|WINDOWS|NATIVE|POSIX|WINDOWSCE} [,major[.minor] ]

Tells the operating system how to run the .EXE file

/SWAPRUN:{NET|CD}

Tells the operating system to copy the linker output to a swap file before running it

/VERBOSE[:LIB]

Prints linker progress messages

/VERSION:major[.minor]

Assigns a version number

/VXD

Creates a virtual device driver (VxD)

/WARN[:level]

Specifies warning level

/WS:AGGRESSIVE

Aggressively trim process memory

옵션

 설명

/ALIGN:number

Specifies the alignment of each section

/BASE:{address | @filename,key}

Sets a base address for the program

/COMMENT:["]comment["]

Inserts a comment string into header

/DEBUG

Creates debugging information

/DEBUGTYPE:CV
/DEBUGTYPE:COFF
/DEBUGTYPE:BOTH

Creates particular formats of debugging information

/DEF:filename

Passes a module-definition (.DEF) file to the linker

/DEFAULTLIB:library

Searches specified library when resolving external references

/DELAY

Controls the delayed loading of DLLs

/DELAYLOAD

Causes the delayed loading of the specified DLL

/DLL

Builds a DLL

/DRIVER[:UPONLY]

Creates a Windows NT kernel mode driver

/ENTRY:function

Sets the starting address

/EXETYPE:DYNAMIC

Builds a virtual device driver

/EXPORT

Exports a function

/FIXED[:NO]

Creates a program that can be loaded only at its preferred base address

/FORCE[:{MULTIPLE|UNRESOLVED}]

Forces link to complete in spite of unresolved or multiply defined symbols

/GPSIZE:#

Specifies the size of communal variables for MIPS and Alpha platforms

/HEAP:reserve[,commit]

Sets the size of the heap in bytes

/IMPLIB:filename

Overrides the default import library name

/INCLUDE:symbol

Forces symbol references

/INCREMENTAL:{YES|NO}

Controls incremental linking

/LARGEADDRESSAWARE

Tells the compiler that the application supports addresses larger than two gigabytes.

/LIBPATH:path

Allows the user to override the environmental library path

/LINK50COMPAT

Generates import libraries in Visual C++ Version 5.0 format

/MACHINE:{IX86|ALPHA|ARM|MIPS|MIPSR41XX|PPC|SH3|SH4}

Specifies the target platform

/MAP

Creates a map file

/MAPINFO:{EXPORTS|FIXUPS|LINES}

Includes the specified information in the map file

/MERGE:from=to

Combines sections

/NODEFAULTLIB[:library]

Ignores all (or specified) default libraries when resolving external references

/NOENTRY

Creates a resource-only DLL

/NOLOGO

Suppresses startup banner

/OPT:{REF|NOREF|ICF[,iterations]|NOICF}

Controls LINK optimizations

/ORDER:@filename

Places COMDATs into the image in a predetermined order

/OUT:filename

Specifies the output file name

/PDB:filename

Creates a program database (.PDB) file

/PDBTYPE:{con[solidate]|sept[ypes]}

Specifies where to store the Program Database (PDB) debug type information.

/PROFILE

Enables profiling (creates a mapfile)

/RELEASE

Sets the checksum in the .EXE header

/SECTION:name,attributes

Overrides the attributes of a section

/STACK:reserve[,commit]

Sets the size of the stack in bytes

/STUB:filename

Attaches an MS-DOS stub program to a Win32 program

/SUBSYSTEM:{CONSOLE|WINDOWS|NATIVE|POSIX|WINDOWSCE} [,major[.minor] ]

Tells the operating system how to run the .EXE file

/SWAPRUN:{NET|CD}

Tells the operating system to copy the linker output to a swap file before running it

/VERBOSE[:LIB]

Prints linker progress messages

/VERSION:major[.minor]

Assigns a version number

/VXD

Creates a virtual device driver (VxD)

/WARN[:level]

Specifies warning level

/WS:AGGRESSIVE

Aggressively trim process memory


'소프트웨어 > C/VC++' 카테고리의 다른 글

[STL] 시퀀스 컨테이너 <Vector>  (0) 2012.05.14
윈속 멀티스레드 서버 (Winsock)  (0) 2012.05.14
간단한 C++ 매크로 만들기  (0) 2010.07.21
CString ->int -> CString  (0) 2010.07.21
CTreeCtrl 검색하기  (0) 2009.11.11
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,
 
 
02 #include <STDIO.H>
03 #define EMPTY
04   
05 #define CHECK1(x, ...) if (!(x)) { printf(__VA_ARGS__); }
06 #define CHECK2(x, ...) if ((x)) { printf(__VA_ARGS__); }
07 #define CHECK3(...) { printf(__VA_ARGS__); }
08 #define MACRO(s, ...) printf(s, __VA_ARGS__)
09   
10 int main() {
11     CHECK1(0, "here %s %s %s", "are", "some", "varargs1(1)\n");
12     CHECK1(1, "here %s %s %s", "are", "some", "varargs1(2)\n");   // won't print
13   
14     CHECK2(0, "here %s %s %s", "are", "some", "varargs2(3)\n");   // won't print
15     CHECK2(1, "here %s %s %s", "are", "some", "varargs2(4)\n");
16   
17     // always invokes printf in the macro
18     CHECK3("here %s %s %s", "are", "some", "varargs3(5)\n");
19   
20     MACRO("hello, world\n");
21     // MACRO("error\n", EMPTY);   would cause C2059
22 }
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

CString → int
int형 = _ttoi(CString형);

int → CString

CString형.Format( _T("%d"), int형);  

블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,