정리

across DLL boundaries (cross-DLL problem)

저장소/VC++

출처 MSDN: https://msdn.microsoft.com/ko-kr/library/ms235460.aspx


실수는 돌고 돌고 반복되고...


static link library로 바꾸거나 run-time library를 md로 변경하거나.

shared_ptr 을 삭제자를 지정해서 사용하면 극복 mt runtime에서 극복 가능??





DLL 경계를 넘어 CRT 개체를 전달할 때 발생할 수 있는 오류

Visual Studio 2015

파일 핸들, 로케일, 환경변수 같은 C Run-time(CRT) 객체를 DLL의 내부 혹은 외부로 전달할 때 ( DLL의 경계를 지나는 함수 호출), DLL 이나 DLL을 호출한 파일에서 서로 다른 CRT 라이브러리 사본을 사용하고 있다면, 예기치 않은 문제가 발생할 수 있습니다.

메모리를 할당하고 (명시적인 new와 malloc이나 암시적으로 strdup, strstreabuf::str 등 ) 할당된 메모리의 포인터를 DLL의 경계를 넘어서 전달한 뒤 이를 해제하게 되면 문제가 발생할 수 있습니다. DLL과 이를 사용하는 쪽에서 CRT 라이브러리의 서로 다른 사본을 사용한다면 메모리 액세스 위반이나 힙 손상이 발생할 수 있습니다.

이 문제의 또 다른 현상으로 디버깅 중 출력창에 다음과 같은 오류가 나타날 수 있습니다.

HEAP[]: 잘못된 주소를 RtlValidateHeap(#,#)로 지정합니다.

CRT라이브러리의 각 복사본은 분리되어 다른 상태에 있습니다. 따라서, 파일 핸들, 환경 변수와 로캘같은 CRT 객체들은 이들 객체들이 할당되어있거나 설정되어있는 CRT의 복사본에 대해서만 유효합니다. DLL과 사용자가 CRT 라이브러리의 여러 복사본을 사용할때, DLL 경계를 넘어 이러한 CRT개체들을 전달할 수 있고 반대편에서 올바르게 선택되기 위해 이들을 제외합니다.

또한, CRT 라이브러리의 각 복사본이 자신의 힙 관리자를 가지기때문에, 하나의 CRT 라이브러리에서 메모리를 할당하는 것과 CRT라이브러리의 다른 복사본으로 해제되기 위한 DLL 경게를 통해 포인터를 전달하는 것은 힙 손상을 잠재적인 원인이 됩니다.

만일 경계를 통해 CRT개체들을 전달하거나 메모리를 할당하거나, DLL외부를 해제하기 위해 DLL을 디자인하는 경우, DLL로 CRT라이브러리의 동일한 복사본을 사용하기 위한 DLL 사용자를 제한합니다. DLL과 이것의 사용자는 둘다 CRT DLL의 같은 버전을 사용하여 연결된 경우에만 CRT라이브러리의 동일한 복사본을 사용합니다. 만일 Visual C++ 4.1또는 그 이전버전으로 빌드된 DLL을 사용하여 Visual C++ 5.0과 함께 혼합된 응용프로그램을 빌드할 경우 이런 문제가 생길 수 있습니다. Visual C++ 4.1에 의해 사용되는 CRT라이브러리의 DLL버전이 msvcrt40.dll이고 Visual 5.0을 사용하는경우 msvcrt.dll을 사용하기 때문에, 이들 DLL들로 CRT라이브러리의 동일한 복사본을 사용하기 위해 응용프로그램을 빌드할 수 없습니다.

그러나 여기에는 예외가 있습니다. 영어 (미국)과 독일어, 프랑스어, 체코어와 같은, Windows 2000의 일부 다른 지역화된 버전에서 msvcrt40.dll(버전 4.20)이 전달됩니다. 결과적으로, msvcrt40.dll을 사용하여 연결된 DLL과 msvcrt.dll을 사용하여 연결된 이것의 사용자들을 통해, 모든 호출이 msvcrt.dll로 전달되어진 msvcrt40.dll에 의해 만들어지기 때문에 CRT라이브러리의 동일한 복사본을 사용할 수 있습니다.

그러나, msvcrt40.dll의 이 전달자 버전은 일본어, 한국어, 중국어와 같은, Windows 2000의 몇몇 지역화된 버전들에서 사용될 수 없습니다. 만일 응용프로그램이 이러한 운영체제를 대상으로 하는 경우, CRT라이브러리의 동일한 복사본을 사용을 필요로 하지 않는 응용프로그램을 고치거나 msvcrt40.dll을 필요로하지 않는 DLL의 업그레이드된 버전을 얻는 것 중에 하나를 필요로 합니다. 만일 DLL을 개발한다면, 이것은 Visual C++ 4.2 또는 그 이후를 사용하여 다시 빌드해야하는 것을 의미합니다. 만일 이것이 제 3자의 DLL이면, 업그레이드에 대한 공급업체에 문의해야 합니다.

이 msvcrt40.dll(버전 4.20)의 전달자 DLL버전은 재배포될수 없음에 주의하세요.

ms235460.collapse_all(ko-kr,VS.140).gif설명

이 예제는 DLL경계를 통해 파일 핸들을 전달합니다.

DLL과 .exe 파일은 /MD를 사용하여 빌드되어서 그들이 CRT의 단일 복사본을 공유합니다.

만일 CRT의 분리된 복사본을 사용하도록 /MT를 사용하여 리빌드된 경우, test1Main.exe 결과를 실행하는 것은 접근 위반에서 실행합니다.

ms235460.collapse_all(ko-kr,VS.140).gif코드

// test1Dll.cpp
// compile with: /MD /LD
#include <stdio.h>
__declspec(dllexport) void writeFile(FILE *stream)
{
   char   s[] = "this is a string\n";
   fprintf( stream, "%s", s );
   fclose( stream );
}

ms235460.collapse_all(ko-kr,VS.140).gif코드

// test1Main.cpp
// compile with: /MD test1dll.lib
#include <stdio.h>
#include <process.h>
void writeFile(FILE *stream);

int main(void)
{
   FILE  * stream;
   errno_t err = fopen_s( &stream, "fprintf.out", "w" );
   writeFile(stream);
   system( "type fprintf.out" );
}

ms235460.collapse_all(ko-kr,VS.140).gifOutput

this is a string

ms235460.collapse_all(ko-kr,VS.140).gif설명

이 예제에서는 DLL 경계를 통해 환경 변수를 전달합니다.

ms235460.collapse_all(ko-kr,VS.140).gif코드

// test2Dll.cpp
// compile with: /MT /LD
#include <stdio.h>
#include <stdlib.h>

__declspec(dllexport) void readEnv()
{
   char *libvar;
   size_t libvarsize;

   /* Get the value of the MYLIB environment variable. */ 
   _dupenv_s( &libvar, &libvarsize, "MYLIB" );

   if( libvar != NULL )
      printf( "New MYLIB variable is: %s\n", libvar);
   else
      printf( "MYLIB has not been set.\n");
   free( libvar );
}

ms235460.collapse_all(ko-kr,VS.140).gif코드

// test2Main.cpp
// compile with: /MT /link test2dll.lib
#include <stdlib.h>
#include <stdio.h>

void readEnv();

int main( void )
{
   _putenv( "MYLIB=c:\\mylib;c:\\yourlib" );
   readEnv();
}

ms235460.collapse_all(ko-kr,VS.140).gifOutput

MYLIB has not been set.

만일 CRT의 복사본을 하나만 사용하도록 /MD과 함께 DLL 및.exe 파일이 빌드되는 경우, 프로그램이 성공적으로 실행하고 다음과 같이 출력됩니다:

New MYLIB variable is: c:\mylib;c:\yourlib


'저장소 > VC++' 카테고리의 다른 글

ATL and MFC String Conversion Macros 사용 시 주의할 점  (0) 2016.04.08
VS2012의 tuple  (0) 2014.09.17
[펌] shlwapi 의 파일 경로 관련 API 모음  (0) 2014.08.13
strftime format 좀 기억하자!  (0) 2014.08.08
SQLite - Syntax  (0) 2014.05.27

ATL and MFC String Conversion Macros 사용 시 주의할 점

저장소/VC++

출처 MSDN : https://msdn.microsoft.com/ko-kr/library/87zae4a3(v=vs.120).aspx


요약:

loop 내에서는 A2W 등의 ATL 3.0 매크로를 쓰지 마라. 스택 오버플로우 문제가 발생할 수 있다.

어쩔 수 없이 써야한다면 ATL 7.0 매크로(CA2WEX class 등)를 사용해야 한다.




ATL and MFC String Conversion Macros

Visual Studio 2013

이 항목에서 설명하는 문자열 변환 매크로는 ATL과 MFC에 모두 사용 가능합니다. MFC 문자열 변환에 대한 자세한 내용은 TN059: MFC MBCS/유니코드 변환 매크로 사용 과 MFC 매크로 및 전역을 참조하세요.

ATL 7.0에는 기존 매크로에 비해 크게 향상된 여러 가지 새 변환 클래스와 매크로가 도입되었습니다.

새로운 문자열 변환 클래스 및 매크로 이름의 형식은 다음과 같습니다.

C SourceType 2[C]DestinationType[EX]

다음은 각 문자에 대한 설명입니다.

  • SourceType 및 DestinationType은 아래 테이블에 설명되어 있습니다.

  • [C]는 대상 형식이 상수여야 하는 경우 표시됩니다.

  • [EX]는 버퍼의 초기 크기가 템플릿 인수로 지정되어야 하는 경우 표시됩니다.

    SourceType/DestinationType

    설명

    A

    ANSI 문자열입니다.

    W

    유니코드 문자열입니다.

    T

    일반 문자열입니다. _UNICODE가 정의된 경우에는 W와 동일하며, 그렇지 않은 경우에는 A와 동일합니다.

    OLE

    OLE 문자열입니다. W와 동일합니다.

예를 들어 변환된 문자열을 변경하지 않고 유니코드 문자열에서 일반 문자열로 변환하려면 CW2CT를 사용합니다.

주의 정보 주의

위에 나열된 패턴의 일부 순열은 지원되지 않습니다. CA2CW 및 CW2CA와 CA2CWEX 및 CW2CAEX는 지원되지 않습니다. OLE 문자열 변환의 경우에는 COLE2T 및 CT2OLE와 COLE2CTCOLE2TEXCOLE2CTEXCT2COLECT2OLEEX 및 CT2COLEEX만 지원됩니다. 자세한 내용은 atlconv.h를 참조하세요.

변환된 문자열이 64자 이하일 가능성이 높은 경우에는 CW2CTEX<64> 등의 EX 버전을 사용하여 스택에서 공간을 절약할 수 있습니다.

참고 참고

BSTR 문자열 간에 변환할 때는 CComBSTR 클래스를 사용하는 것이 좋습니다. BSTR로 변환하려면 기존 문자열을 CComBSTR의 생성자로 전달합니다. BSTR에서 변환하려면 COLE2T와 같은 COLE2[C]DestinationType[EX]를 사용합니다.

버퍼가 필요한 새 변환 클래스(CA2AEXCA2WEXCW2AEX 및 CW2WEX)는 고정 크기 정적 버퍼를 사용하여 변환 결과를 저장합니다. 결과가 너무 커서 정적 버퍼에 포함할 수 없는 경우 클래스는 malloc를 사용하여 메모리를 할당함으로써 개체가 범위를 벗어나면 메모리를 해제합니다. 따라서 이전의 텍스트 변환 매크로와는 달리 이러한 클래스를 루프에서도 안전하게 사용할 수 있으며 스택이 오버플로되지 않습니다.

ATL 7.0에 도입된 변환 매크로는 입력 NULL 문자열을 인식하도록 최적화되어 있습니다. 입력 매개 변수가 NULL이면 이러한 매크로는 메모리를 할당하지 않고 NULL을 반환합니다.

기본적으로 ATL 변환 클래스와 매크로는 현재 스레드의 ANSI 코드 페이지를 변환에 사용합니다. CA2WEX 또는 CW2AEX 클래스 기반 매크로를 사용하는 특정 변환에 대해 이 동작을 재정의하려는 경우 코드 페이지를 클래스 생성자에 대한 두 번째 매개 변수로 지정합니다.

보안 정보 보안 정보

버퍼 오버런 문제 발생 가능성을 방지하려면 문자열을 이러한 매크로로 전달하기 전에 문자열의 길이를 확인합니다. 스택 오버플로는 try/except를 통해서도 catch할 수 있는 예외입니다.

이전 문자열 변환 매크로와 새로운 문자열 변환 클래스의 몇 가지 중요한 차이점은 다음과 같습니다.

이전 ATL 3.0 변환 매크로

새 ATL 7.0 변환 클래스

스택에 메모리를 할당합니다.

작은 문자열에 대해 스택 메모리를 사용합니다. 스택이 충분히 크지 않으면 힙을 사용합니다.

함수가 종료되면 문자열이 해제됩니다.

변수가 범위를 벗어나면 문자열이 해제됩니다.

예외 처리기에서는 사용할 수 없습니다.

예외 처리기에서 사용할 수 있습니다.

루프에 사용하기 적합하지 않습니다. 함수가 종료될 때까지 메모리 사용이 증가합니다.

루프에서 사용할 수 있습니다. 루프 범위가 적용되므로 각 반복에서 메모리가 해제됩니다.

큰 문자열의 경우에는 효율적이지 않습니다. 스택 공간이 제한됩니다.

큰 문자열에 사용해도 문제가 없습니다. 문자열은 힙에 할당됩니다.

보통 USES_CONVERSION을 정의해야 합니다.

USES_CONVERSION을 정의하지 않아도 됩니다.

OLE의 의미가 OLE2ANSI 정의에 따라 달라집니다.

OLE는 항상 W와 동일합니다.

//Example 1 
// Convert LPCWSTR to LPCSTR. 
void ExampleFunction1(LPCWSTR pszW)
{
   // Create an instance of CW2A, called pszA, 
   // and initialize it with pszW.
   CW2A pszA(pszW);
   // pszA works like an LPCSTR, and can be used thus:
   ExampleFunctionA(pszA);  
   // Note: pszA will become invalid when it goes out of scope.
}

// Example 2 
// Use a temporary instance of CW2A. 
void ExampleFunction2(LPCWSTR pszW)
{
   // Create a temporary instance of CW2A, 
   // and initialize it with pszW.
   ExampleFunctionA(CW2A(pszW));
   // Note: the temporary instance becomes invalid  
   // after the execution of the statement above.
}

// Example 3 
// Incorrect use of conversion macros. 
void ExampleFunction3(LPCWSTR pszW)
{
   // Create a temporary instance of CW2A, 
   // save a pointer to it and then delete 
   // the temportary instance.
   LPCSTR pszA = CW2A(pszW);
   // The pszA in the following line is an invalid pointer, 
   // as the instance of CW2A has gone out of scope.
   ExampleFunctionA(pszA);
}

아래 코드는 효율적인 코드가 아닙니다.

LPCTSTR szr = CA2T(szReplaceFile);

ATL 3.0 매크로를 사용하면 다음 코드를 사용할 수 있습니다.

LPCTSTR szr = A2T(szReplaceFile);   

현재 함수가 종료될 때까지 변환 함수가 할당한 메모리가 해제되지 않습니다. 그러나 새 클래스에서는 위와 같은 코드가 작동하지 않습니다.

아래 코드는

LPCTSTR szr = CA2T(szReplaceFile);   

다음 코드 조각과 일치합니다.

LPCTSTR szr;
{
   CA2T temp(szReplaceFile);
   szr = temp.operator LPTSTR();
}   

임시 개체가 제거되면 해당 임시 개체가 할당하고 캐스트 연산자에서 반환된 메모리도 제거되므로, szr의 값을 사용하면 원하는 결과를 얻을 수 없습니다.

대신 다음 코드를 사용합니다.

CA2T szr(szReplaceFile);   

캐스트 연산자는 CA2T 개체를 LPCTSTR과 같이 표시합니다.

기본 정적 버퍼 크기는 128자입니다. 특정 변환에 대해 버퍼 크기를 변경해야 하는 경우 매크로의 EX 버전을 사용하고 템플릿 인수로 버퍼 크기를 지정합니다.

// Example 4 
// Changing the size of the buffer. 
void ExampleFunction4(LPCWSTR pszW)
{
   // Use a 16-character buffer.
   ExampleFunctionA(CW2AEX<16>(pszW));
}

아래에는 클래스의 생성자에 대해 코드 페이지를 두 번째 매개 변수로 지정하는 예가 나와 있습니다.

// Example 5 
// Specifying the code page. 
void ExampleFunction5(LPCWSTR pszW)
{
   // Convert to the Macintosh code page
   ExampleFunctionA(CW2A(pszW, CP_MACCP));
}

아래 테이블에 나와 있는 원래 텍스트 변환 매크로도 계속 사용할 수 있습니다.

ATL 3.0 문자열 변환 매크로

A2BSTR

OLE2A

T2A

W2A

A2COLE

OLE2BSTR

T2BSTR

W2BSTR

A2CT

OLE2CA

T2CA(사용되지 않음. 대신 T2CA_EX 또는 CT2CA 사용)

W2CA

A2CW

OLE2CT

T2COLE

W2COLE

A2OLE

OLE2CW

T2CW

W2CT

A2T

OLE2T

T2OLE

W2OLE

A2W

OLE2W

T2W

W2T

이러한 매크로 사용을 위한 구문은 다음과 같습니다.

MACRONAME( string_address )

예를 들면 다음과 같습니다.

A2W(lpa);

매크로 이름에서 소스 문자열 형식은 왼쪽에 있고(예: A) 대상 문자열 형식은 오른쪽에 있습니다(예: W). A는 LPSTR을, OLE는 LPOLESTR을, TLPTSTR을, W는 LPWSTR을 나타냅니다.

이름에 C가 있는 매크로는 소스 문자열을 const 문자열로 변환합니다. 예를 들어 W2CA는 LPWSTR을 LPCSTR로 변환합니다.

따라서 A2W는 LPSTR을 LPWSTR로 변환하고 OLE2T는 LPOLESTR을 LPTSTR로 변환하는 식으로 변환이 수행됩니다.

ATL 문자열 변환 매크로의 동작은 적용 중인 컴파일러 지시문(있는 경우)에 따라 달라집니다. 소스와 대상 형식이 같으면 변환이 수행되지 않습니다. 컴파일러 지시문은 T 및 OLE를 다음과 같이 변경합니다.

적용되는 컴파일러 지시문

T의 변경 결과

OLE의 변경 결과

없음

A

W

_UNICODE

W

W

OLE2ANSI

A

A

_UNICODE 및 OLE2ANSI

W

A

대상 형식이 BSTR인 경우를 제외하고 _alloca를 사용하여 대상 문자열을 만듭니다. _alloca를 사용하는 경우 스택 외부에 메모리가 할당되므로 함수가 반환될 때 자동으로 정리됩니다. 이 매크로는 기본적으로 한 번에 최대 500KB까지만 변환합니다.

ATL 문자열 변환 매크로를 사용할 때는 컴파일러 오류를 방지하기 위해 함수 시작 부분에 USES_CONVERSION 매크로를 지정합니다. 예를 들면 다음과 같습니다.

void StringFunc(LPSTR lpsz)
{
   USES_CONVERSION;

   LPWSTR x = A2W(lpsz);
   // Do something with x
   wprintf_s(L"x is %s", x);
}

헤더 파일: AtlBase.h, AtlConv.h(AtlConv.h에 선언됨)


'저장소 > VC++' 카테고리의 다른 글

across DLL boundaries (cross-DLL problem)  (0) 2016.04.08
VS2012의 tuple  (0) 2014.09.17
[펌] shlwapi 의 파일 경로 관련 API 모음  (0) 2014.08.13
strftime format 좀 기억하자!  (0) 2014.08.08
SQLite - Syntax  (0) 2014.05.27

shared workspace plugin

저장소/Jenkins

Build Trigger의 'Poll SCM' 사용 시 shared workspace의 variable ${SHAREDSPACE_SCM_URL} 사용이 안 된다.

아래 내용 참고.



link : https://wiki.jenkins-ci.org/display/JENKINS/Shared+workspace+plugin



This plugin allows to share workspaces by Jenkins jobs with the same SCM repos.

It should save you some disk space, if you have different jobs with identical repos.

How to use it:

1) In "Manage Jenkins"->"Configure System" find new "Workspace Sharing" block.

2) Add some Name + SCM Repo URL pairs. Save.

3) Go to the job configuration page, now you able to select "Shared Workspace" here.

4) Use ${SHAREDSPACE_SCM_URL} variable in your SCM url field.

Workspaces will be created as {node remote FS root}/sharedspace/{workspace name}


Known issues:

 - SCM polling not working for now, plugin should be improved.

 - sometimes, on fresh copied job, shared-space url parameter not saving to config on first "save", you should save job twice to be sure.

New in 1.0.2

  • Support for matrix-build projects


'저장소 > Jenkins' 카테고리의 다른 글

[LINK] Build Trigger  (0) 2016.03.23
syntax of cron  (0) 2016.03.23

[LINK] Build Trigger

저장소/Jenkins



http://blog.naver.com/special9486/220274932377

'저장소 > Jenkins' 카테고리의 다른 글

shared workspace plugin  (0) 2016.03.23
syntax of cron  (0) 2016.03.23

syntax of cron

저장소/Jenkins

출처: http://htmlpreview.github.io/?https://github.com/jenkinsci/jenkins/blob/master/core/src/main/resources/hudson/triggers/TimerTrigger/help-spec.html




This field follows the syntax of cron (with minor differences). Specifically, each line consists of 5 fields separated by TAB or whitespace:

MINUTE HOUR DOM MONTH DOW

MINUTE Minutes within the hour (0–59)

HOUR The hour of the day (0–23)

DOM The day of the month (1–31)

MONTH The month (1–12)

DOW The day of the week (0–7) where 0 and 7 are Sunday.

To specify multiple values for one field, the following operators are available. In the order of precedence,


* specifies all valid values

M-N specifies a range of values

M-N/X or */X steps by intervals of X through the specified range or whole valid range

A,B,...,Z enumerates multiple values

To allow periodically scheduled tasks to produce even load on the system, the symbol H (for “hash”) should be used wherever possible. For example, using 0 0 * * * for a dozen daily jobs will cause a large spike at midnight. In contrast, using H H * * * would still execute each job once a day, but not all at the same time, better using limited resources.


The H symbol can be used with a range. For example, H H(0-7) * * * means some time between 12:00 AM (midnight) to 7:59 AM. You can also use step intervals with H, with or without ranges.


The H symbol can be thought of as a random value over a range, but it actually is a hash of the job name, not a random function, so that the value remains stable for any given project.


Beware that for the day of month field, short cycles such as */3 or H/3 will not work consistently near the end of most months, due to variable month lengths. For example, */3 will run on the 1st, 4th, …31st days of a long month, then again the next day of the next month. Hashes are always chosen in the 1-28 range, so H/3 will produce a gap between runs of between 3 and 6 days at the end of a month. (Longer cycles will also have inconsistent lengths but the effect may be relatively less noticeable.)


Empty lines and lines that start with # will be ignored as comments.


In addition, @yearly, @annually, @monthly, @weekly, @daily, @midnight, and @hourly are supported as convenient aliases. These use the hash system for automatic balancing. For example, @hourly is the same as H * * * * and could mean at any time during the hour. @midnight actually means some time between 12:00 AM and 2:59 AM.


Examples:


# every fifteen minutes (perhaps at :07, :22, :37, :52)

H/15 * * * *

# every ten minutes in the first half of every hour (three times, perhaps at :04, :14, :24)

H(0-29)/10 * * * *

# once every two hours every weekday (perhaps at 9:38 AM, 11:38 AM, 1:38 PM, 3:38 PM)

H 9-16/2 * * 1-5

# once a day on the 1st and 15th of every month except December

H H 1,15 1-11 *

'저장소 > Jenkins' 카테고리의 다른 글

shared workspace plugin  (0) 2016.03.23
[LINK] Build Trigger  (0) 2016.03.23

VS2012의 tuple

저장소/VC++


Visual Studio 2012의 tuple 사용 시 make_tuple의 파라메터 수는 4개인가 5개로 제한.

늘리기 위해서는 전처리기에 다음과 같이 추가.

_VARIADIC_MAX=10


최대 10개밖에 안 된다고 한다. 잊지 말자~

[펌] shlwapi 의 파일 경로 관련 API 모음

저장소/VC++

출처 : http://anysoft.co.kr/bbs/board.php?bo_table=dev&wr_id=24




참조: http://msdn.microsoft.com/en-us/library/bb773559(VS.85).aspx

윈도우의 Visual C++에서 파일 경로를 조작할 때 사용할 수 있는 유용한 API 함수들이다.
사용하기 위해 아래와 같이 선언한다.
#include <shlwapi.h> #pragma comment(lib, "shlwapi")

PathAddBackslash - 경로에 백슬레시를 덧붙여준다. 백슬레시가 이미 붙어 있으면 변경하지 않는다.
"c:\abc" -> "c:\abc\"
"c:\abc\" -> "c:\abc\"

PathAddExtension - 파일 경로 뒤에 지정된 확장자를 덧붙여준다. 확장자가 이미 있다면 변경하지 않는다.
"c:\abc", ".bak" -> "c:\abc.bak"
"c:\abc.cpp", ".tmp" -> "c:\abc.cpp"

PathAppend - 두 개의 경로를 덧붙인다. 사이에 백슬레시가 없으면 자동으로 추가해 준다.
"c:\abc", "def" -> "c:\abc\def"
"c:\abc\", "def" -> "c:\abc\def"
"c:\abc", "\def" -> "c:\abc\def"
"c:\abc\", "\def" -> "c:\abc\def"

PathBuildRoot - 드라이브 식별번호를 드라이브 경로로 변경해 준다.
0 -> "A:\"
1 -> "B:\"
2 -> "C:\"

PathCanonicalize - 특별한 경로 문자열을 정리해 준다.
"c:\abc\def\..\ghi" -> "c:\abc\ghi"
"c:\abc\def\.\ghi" -> "c:\abc\def\ghi"

PathCombine - 두 개의 경로를 결합한다. 백슬레시도 검사해서 추가하고 ., ..과 같은 특별한 경로 문자열도 정리해 준다.
"c:\abc", "def.txt" -> "c:\abc\def.txt"
"c:\abc\", "..\def\ghi.txt" -> "c:\def\ghi.txt"

PathCommonPrefix -  공통된 경로를 골라낸다.
"c:\abc\def.txt", "c:\abc\ghi\" -> "c:\abc"
"c:\abc\def\jkl.txt", "c:\abc\def\..\jkl.txt" -> "c:\abc\def"

PathCompactPath -  경로를 dc와 pixel 폭 크기에 알맞게 적당히 줄여준다.
hDC, "c:\abc\def\ghi\jkl.txt", 100 -> "c:\abc\...\jkl.txt"

PathCompactPathEx - 경로를 최대 문자열 길이에 알맞게 적당히 줄여준다.
"c:\\abc\\def\\jkl.txt", 15 -> "c:\...\jkl.txt"

PathCreateFromUrl - URL로 쓰여진 파일명을 경로로 변환한다.
"file:///c:/abc/def.txt" -> "c:\abc\def.txt"

PathFileExists - 해당 경로나 파일이 실제로 존재하는지 검사한다.

PathFindExtension - 확장자의 위치를 찾아서 반환한다.
"c:\abc\def.txt" -> ".txt"

PathFindFileName - 파일 이름의 위치를 찾아서 반환한다.
"c:\abc\def.txt -> "def.txt"

PathFindNextComponent - 전체 경로 중 한 단계씩 하위로 내려간 경로를 반환한다.
"c:\abc\def.txt" -> "abc\def.txt"
"abc\def.txt" -> "def.txt"
"def.txt" -> ""

PathFindOnPath - 파일을 찾아서 완전한 경로를 반환한다. (목록이 NULL일 경우 실행 PATH에서 찾기)
"cmd.exe", NULL -> "C:\WINDOWS\system32\cmd.exe"
"iexplore.exe", { "c:\Windows", "c:\Program Files", "c:\Program Files\Internet Explorer", NULL } -> "c:\Program Files\Internet Explorer\iexplore.exe"
파일이 여러개라면 첫번째로 발견된 파일의 경로만 반환

PathFindSuffixArray - 지정된 접미사 목록에서 입력된 경로에 일치하는 것을 찾는다. (대소문자 구분)
"c:\abc\DEF.txt", { "def.txt", "DEF.txt", ".txt" }, 3 -> "DEF.txt"
"c:\abc\def\ghi.txt", { "def.txt", "DEF.txt", ".txt" }, 3 -> ".txt"

PathGetArgs - 전체 문자열에서 앞 단어를 무시한 입력 인자 위치를 찾아서 반환한다.
"test.exe temp.txt sample.doc" -> "temp.txt sample.doc"
"test.exe sample All 15" -> "sample All 15"
"test.exe" -> ""
"abc def ghi" -> "def ghi"

PathGetCharType - 문자가 경로에서 어떤 목적으로 쓰일 수 있는지 확인한다.
':' -> GCT_SEPARATOR
'.' -> GCT_LFNCHAR | GCT_SHORTCHAR
'\\' -> GCT_SEPARATOR
'/' -> GCT_INVALID
'\"' -> GCT_INVALID
'\'' -> GCT_LFNCHAR | GCT_SHORTCHAR
'\t' -> GCT_INVALID
'\n' -> GCT_INVALID
',' -> GCT_LFNCHAR
'*' -> GCT_WILD
'?' -> GCT_WILD
입력된 문자열을 검색하면서 리턴값을 조사하면 올바른 경로인지 미리 검사할 수 있다.

PathGetDriveNumber - 경로가 어느 드라이브에 있는지 번호를 확인한다.
"c:\abc\def.txt" -> 2
"d:" -> 3
"s:\test" -> 18

PathIsContentType - 파일 확장자가 콘텐츠 형식과 일치하는지 확인한다.
"c:\abc\def.txt", "text/plain" -> TRUE
".txt", "text/plain" -> TRUE
"txt", "text/plain" -> FALSE

PathIsDirectory - 실제로 존재하는 폴더인지 확인한다.
"c:\windows" -> TRUE
"c:\abc" -> FALSE

PathIsDirectoryEmpty - 폴더 내부가 비어있는지 확인한다.
"c:\windows" -> FALSE

PathIsFileSpec - 주어진 경로에 경로 문자들이 없는지 확인한다. 결과가 참이라도 올바른 파일명이 아닐 수 있다.
"c:\abc\def.txt" -> FALSE
"test.txt" -> TRUE
"*/wow." -> TRUE

PathIsHTMLFile - 콘텐츠 형식이 "text/html"인 확장자인지 확인한다.
"test.html" -> TRUE
"test.htm" -> TRUE
"test.xml" -> FALSE
"test.txt" -> FALSE

PathIsLFNFileSpec - 주어진 경로가 긴파일이름에 적합한지 확인한다.

PathIsNetworkPath - 주어진 경로가 네트워크 경로 형식인지 확인한다. (실제로 존재하는지 확인하지는 않음)
"c:\abc\def.txt" -> FALSE
"\\abc\def.txt" -> TRUE
"http://abc/def.txt" -> FALSE

PathIsPrefix - 경로가 주어진 위치에서 시작하는지 확인한다.
"c:\", "c:\abc" -> TRUE
"C:\", "c:\abc" -> TRUE
"c:", "c:\abc" -> FALSE
"..\abc", "..\abc\def" -> TRUE
"d:\abc", "d:\def" -> FALSE

PathIsRelative - 주어진 경로가 상대 경로인지 확인한다. (파일명만 있어도 상대 경로로 인정)
".\abc.txt" -> TRUE
"..\abc\def.txt" -> TRUE
"c:\abc\def.txt" -> FALSE
"c:\abc\..\def.txt" -> FALSE
"test.txt" -> TRUE

PathIsRoot - 주어진 경로가 드라이브 루트인지 검사한다.
"c:\" -> TRUE
"c:" -> FALSE
"c:\test.txt" -> FALSE

PathIsSameRoot - 주어진 경로가 같은 드라이브에 있는지 검사한다.
"c:\abc\def", "c:\test.txt" -> TRUE

PathIsSystemFolder - 시스템 속성을 가진 폴더인지 확인한다.
"c:\windows" -> FALSE
"c:\program files" -> TRUE
"C:\Documents and Settings" -> FALSE
"C:\Documents and Settings\All Users\Application Data" -> TRUE

PathIsUNC - 네트워크 공유 경로인지 확인한다. (실제로 존재하는지 확인하지는 않음)
"c:\abc\def" -> FALSE
"\\abc\def" -> TRUE
"\\192.168.0.1" -> TRUE
"\\abc\def.txt" -> TRUE
"\\" -> TRUE
"\\test.txt" -> TRUE

PathIsUNCServer - 네트워크 공유 서버인지 확인한다. (실제로 존재하는지 확인하지는 않음)
"c:\abc\def" -> FALSE
"\\abc\def" -> FALSE
"\\192.168.0.1" -> TRUE
"\\abc\def.txt" -> FALSE
"\\" -> TRUE
"\\test.txt" -> TRUE

PathIsUNCServerShare -  네트워크 공유 폴더인지 확인한다. (실제로 존재하는지 확인하지는 않음)
"c:\abc\def" -> FALSE
"\\abc\def" -> TRUE
"\\192.168.0.1" -> FALSE
"\\abc\def.txt" -> TRUE
"\\" -> FALSE
"\\test.txt" -> FALSE

PathIsURL - 주어진 경로가 URL 형식이 맞는지 확인한다.

PathMakePretty - 대문자로 만들어진 경로 문자열을 소문자로 변환한다. (소문자가 하나라도 있으면 실패)
"C:\ABC\DEF" -> TRUE, "C:\abc\def"
"c:\ABC\DEF" -> FALSE, "c:\ABC\DEF"
"C:\abc\DEF" -> FALSE, "C:\abc\DEF"

PathMakeSystemFolder - 지정된 폴더를 시스템 폴더로 만든다.

PathMatchSpec - 와일드카드 형식으로 파일명과 일치되는지 확인한다.
"test.txt", "*.txt" -> TRUE
"abc.txt", "ab?.*" -> TRUE
"c:\abc\def.txt", "*\???.txt" -> TRUE

PathParseIconLocation - 파일 경로와 아이콘 인덱스 번호를 분리한다.
"iexplore.exe, 1" -> 1, "iexplore.exe"

PathQuoteSpaces - 경로에 공백이 포함되어 있으면 큰따옴표로 묶어준다. 공백이 없으면 무시
c:\1. abc -> "c:\\1. abc"
c:\abc -> c:\abc

PathRelativePathTo - 한 경로에서 다른 경로로 가는 상대 경로를 추출한다. (같은 드라이브에서만 가능)
"c:\abc\def\ghi\jkl.txt", 0, "c:\abc\mno\pqr.txt", 0 -> TRUE, "..\..\mno\pqr.txt"
"c:\abc\def\ghi\jkl", FILE_ATTRIBUTE_DIRECTORY, "c:\abc\mno\pqr.txt", 0
-> TRUE, "..\..\..\mno\pqr.txt"
"c:\abc\def\ghi\jkl.txt", 0, "c:\abc\mno\pqr", FILE_ATTRIBUTE_DIRECTORY
-> TRUE, "..\..\mno\pqr"

PathRemoveArgs - 경로에 포함된 인자를 지운다.
"test.exe temp.txt sample.doc" -> "test.exe"
"test.exe sample All 15" -> "test.exe"
"test.exe" -> "test.exe"
"abc def ghi" -> "abc"

PathRemoveBackslash - 경로 끝에 백슬레시가 있으면 삭제한다.
"c:\abc\" -> "c:\abc"
"c:\abc" -> "c:\abc"

PathRemoveBlanks - 경로 앞뒤에 공백문자가 있으면 삭제한다.
"  c:\abc   " -> "c:\abc"

PathRemoveExtension - 확장자를 삭제한다.
"c:\abc\def.txt" -> "c:\abc\def"

PathRemoveFileSpec - 파일 이름을 삭제한다.
"c:\abc\def.txt" -> "c:\abc"
"c:\abc\def\" -> "c:\abc\def"

PathRenameExtension - 확장자를 교체한다.
"c:\abc\def.txt", ".bak" -> "c:\abc\def.bak"
"c:\abc\def", ".bak" -> "c:\abc\def.bak"
"c:\abc\def\", ".bak" -> "c:\abc\def\.bak"

PathSearchAndQualify - 주어진 경로의 오류를 바로잡고, 상대 경로도 정리하고, 환경 변수도 적용한다.
"C:\foo\." -> "C:\foo"
"C:\foo\baz\.." -> "C:\foo"
"C:\foo\\\baz" -> "C:\foo\baz"
"\\server\aa\..\bb" -> "\\server\aa\bb"
"notepad.exe" -> "C:\Windows\System32\notepad.exe"
"%SystemRoot%\System32\notepad.exe" -> "C:\Windows\System32\notepad.exe"
(XP에서는 환경변수 확장이 제대로 작동하지 않음)

PathSetDlgItemPath - 주어진 다이얼로그 아이템 윈도우의 크기에 알맞게 긴 경로를 적당히 줄여준다.

PathSkipRoot - 루트 경로를 제외한 첫번째 위치를 찾아서 반환한다.
"c:\abc\def" -> "abc\def"
"\\\\abc\\def\\ghi.txt" -> "ghi.txt"

PathStripPath - 가장 마지막 경로만 남기고 삭제한다.
"c:\abc\def.txt" -> "def.txt"
"c:\abc\def" -> "def"
"c:\abc\def\" -> "def\"

PathStripToRoot - 루트 경로만 남기고 삭제한다.
"c:\abc\def.txt" -> "c:\"
"c:\abc\def" -> "c:\"

PathUndecorate - 경로에서 임시 파일에 붙는 숫자를 삭제한다.
"C:\Path\File[5].txt" -> "C:\Path\File.txt"
"C:\Path\File[12]" -> "C:\Path\File"
"C:\Path\File.txt" -> "C:\Path\File.txt"
"C:\Path\[3].txt" -> "C:\Path\[3].txt"
인터넷으로 접근한 임시파일들은 [#]과 같은 식으로 번호가 뒤에 붙는데 그러한 임시 번호를 제거한다.

PathUnExpandEnvStrings - 경로에서 환경 변수에 해당하는 문자열을 환경 변수 이름으로 교체한다.
"c:\Windows\test.txt" -> "%SystemRoot%\test.txt"
"c:\program files\test.txt" -> "%
ProgramFiles%\test.txt"
"c:\abc\def" -> "%SystemDrive%\
abc\def"

PathUnmakeSystemFolder - 지정된 폴더의 시스템 속성을 해제한다.

PathUnquoteSpaces - 큰 따옴표로 감싸진 
경로에서 따옴표를 제거한다.
"c:\abc\1 def" -> c:\abc\1 def
c:\abc\def -> c:\abc\def


'저장소 > VC++' 카테고리의 다른 글

ATL and MFC String Conversion Macros 사용 시 주의할 점  (0) 2016.04.08
VS2012의 tuple  (0) 2014.09.17
strftime format 좀 기억하자!  (0) 2014.08.08
SQLite - Syntax  (0) 2014.05.27
SHFileOperation API (RemoveDirectory API 대체 사용)  (0) 2014.04.30

strftime format 좀 기억하자!

저장소/VC++

출처 : MSDN

http://msdn.microsoft.com/en-us/library/fe06s4ak.aspx


MFC CTime의 Format 함수에서도 strftime의 포맷과 동일하게 사용한다. 참고하자.




The formatting codes for strftime are listed below:

%a

Abbreviated weekday name

%A

Full weekday name

%b

Abbreviated month name

%B

Full month name

%c

Date and time representation appropriate for locale

%d

Day of month as decimal number (01 – 31)

%H

Hour in 24-hour format (00 – 23)

%I

Hour in 12-hour format (01 – 12)

%j

Day of year as decimal number (001 – 366)

%m

Month as decimal number (01 – 12)

%M

Minute as decimal number (00 – 59)

%p

Current locale's A.M./P.M. indicator for 12-hour clock

%S

Second as decimal number (00 – 59)

%U

Week of year as decimal number, with Sunday as first day of week (00 – 53)

%w

Weekday as decimal number (0 – 6; Sunday is 0)

%W

Week of year as decimal number, with Monday as first day of week (00 – 53)

%x

Date representation for current locale

%X

Time representation for current locale

%y

Year without century, as decimal number (00 – 99)

%Y

Year with century, as decimal number

%z, %Z

Either the time-zone name or time zone abbreviation, depending on registry settings; no characters if time zone is unknown

%%

Percent sign

As in the printf function, the # flag may prefix any formatting code. In that case, the meaning of the format code is changed as follows.

Format code

Meaning

%#a, %#A, %#b, %#B, %#p, %#X, %#z, %#Z, %#%

# flag is ignored.

%#c

Long date and time representation, appropriate for current locale. For example: "Tuesday, March 14, 1995, 12:41:29".

%#x

Long date representation, appropriate to current locale. For example: "Tuesday, March 14, 1995".

%#d, %#H, %#I, %#j, %#m, %#M, %#S, %#U, %#w, %#W, %#y, %#Y

Remove leading zeros (if any).


'저장소 > VC++' 카테고리의 다른 글

VS2012의 tuple  (0) 2014.09.17
[펌] shlwapi 의 파일 경로 관련 API 모음  (0) 2014.08.13
SQLite - Syntax  (0) 2014.05.27
SHFileOperation API (RemoveDirectory API 대체 사용)  (0) 2014.04.30
SQLite - insert or replace (upsert)  (0) 2014.04.29

SQLite - Syntax

저장소/VC++




SQLite is followed by unique set of rules and guidelines called Syntax. This tutorial gives you a quick start with SQLite by listing all the basic SQLite Syntax.

Case Sensitivity

Important point to be noted is that SQLite is case insensitive, but there are some commands, which are case sensitive like GLOB and glob have different meaning in SQLite statements.

Comments

SQLite comments are extra notes, which you can add in your SQLite code to increase its readability and they can appear anywhere; whitespace can occur, including inside expressions and in the middle of other SQL statements but they can not be nested.

SQL comments begin with two consecutive "-" characters (ASCII 0x2d) and extend up to and including the next newline character (ASCII 0x0a) or until the end of input, whichever comes first.

You can also use C-style comments, which begin with "/*" and extend up to and including the next "*/" character pair or until the end of input, whichever comes first. C-style comments can span multiple lines.

sqlite>.help -- This is a single line comment

SQLite Statements

All the SQLite statements start with any of the keywords like SELECT, INSERT, UPDATE, DELETE, ALTER, DROP, etc., and all the statements end with a semicolon (;).

SQLite ANALYZE Statement:

ANALYZE;
or
ANALYZE database_name;
or
ANALYZE database_name.table_name;

SQLite AND/OR Clause:

SELECT column1, column2....columnN
FROM   table_name
WHERE  CONDITION-1 {AND|OR} CONDITION-2;

SQLite ALTER TABLE Statement:

ALTER TABLE table_name ADD COLUMN column_def...;

SQLite ALTER TABLE Statement (Rename):

ALTER TABLE table_name RENAME TO new_table_name;

SQLite ATTACH DATABASE Statement:

ATTACH DATABASE 'DatabaseName' As 'Alias-Name';

SQLite BEGIN TRANSACTION Statement:

BEGIN;
or
BEGIN EXCLUSIVE TRANSACTION;

SQLite BETWEEN Clause:

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name BETWEEN val-1 AND val-2;

SQLite COMMIT Statement:

COMMIT;

SQLite CREATE INDEX Statement :

CREATE INDEX index_name
ON table_name ( column_name COLLATE NOCASE );

SQLite CREATE UNIQUE INDEX Statement :

CREATE UNIQUE INDEX index_name
ON table_name ( column1, column2,...columnN);

SQLite CREATE TABLE Statement:

CREATE TABLE table_name(
   column1 datatype,
   column2 datatype,
   column3 datatype,
   .....
   columnN datatype,
   PRIMARY KEY( one or more columns )
);

SQLite CREATE TRIGGER Statement :

CREATE TRIGGER database_name.trigger_name 
BEFORE INSERT ON table_name FOR EACH ROW
BEGIN 
   stmt1; 
   stmt2;
   ....
END;

SQLite CREATE VIEW Statement :

CREATE VIEW database_name.view_name  AS
SELECT statement....;

SQLite CREATE VIRTUAL TABLE Statement:

CREATE VIRTUAL TABLE database_name.table_name USING weblog( access.log );
or
CREATE VIRTUAL TABLE database_name.table_name USING fts3( );

SQLite COMMIT TRANSACTION Statement:

COMMIT;

SQLite COUNT Clause:

SELECT COUNT(column_name)
FROM   table_name
WHERE  CONDITION;

SQLite DELETE Statement:

DELETE FROM table_name
WHERE  {CONDITION};

SQLite DETACH DATABASE Statement:

DETACH DATABASE 'Alias-Name';

SQLite DISTINCT Clause:

SELECT DISTINCT column1, column2....columnN
FROM   table_name;

SQLite DROP INDEX Statement :

DROP INDEX database_name.index_name;

SQLite DROP TABLE Statement:

DROP TABLE database_name.table_name;

SQLite DROP VIEW Statement :

DROP INDEX database_name.view_name;

SQLite DROP TRIGGER Statement :

DROP INDEX database_name.trigger_name;

SQLite EXISTS Clause:

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name EXISTS (SELECT * FROM   table_name );

SQLite EXPLAIN Statement :

EXPLAIN INSERT statement...;
or 
EXPLAIN QUERY PLAN SELECT statement...;

SQLite GLOB Clause:

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name GLOB { PATTERN };

SQLite GROUP BY Clause:

SELECT SUM(column_name)
FROM   table_name
WHERE  CONDITION
GROUP BY column_name;

SQLite HAVING Clause:

SELECT SUM(column_name)
FROM   table_name
WHERE  CONDITION
GROUP BY column_name
HAVING (arithematic function condition);

SQLite INSERT INTO Statement:

INSERT INTO table_name( column1, column2....columnN)
VALUES ( value1, value2....valueN);

SQLite IN Clause:

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name IN (val-1, val-2,...val-N);

SQLite Like Clause:

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name LIKE { PATTERN };

SQLite NOT IN Clause:

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name NOT IN (val-1, val-2,...val-N);

SQLite ORDER BY Clause:

SELECT column1, column2....columnN
FROM   table_name
WHERE  CONDITION
ORDER BY column_name {ASC|DESC};

SQLite PRAGMA Statement:

PRAGMA pragma_name;

For example:

PRAGMA page_size;
PRAGMA cache_size = 1024;
PRAGMA table_info(table_name);

SQLite RELEASE SAVEPOINT Statement:

RELEASE savepoint_name;

SQLite REINDEX Statement:

REINDEX collation_name;
REINDEX database_name.index_name;
REINDEX database_name.table_name;

SQLite ROLLBACK Statement:

ROLLBACK;
or
ROLLBACK TO SAVEPOINT savepoint_name;

SQLite SAVEPOINT Statement:

SAVEPOINT savepoint_name;

SQLite SELECT Statement:

SELECT column1, column2....columnN
FROM   table_name;

SQLite UPDATE Statement:

UPDATE table_name
SET column1 = value1, column2 = value2....columnN=valueN
[ WHERE  CONDITION ];

SQLite VACUUM Statement:

VACUUM;

SQLite WHERE Clause:

SELECT column1, column2....columnN
FROM   table_name
WHERE  CONDITION;


SHFileOperation API (RemoveDirectory API 대체 사용)

저장소/VC++

RemoveDirectory API의 경우 폴더에 하위 구성이 존재할 경우 실패 발생.

SHFileOperation API 사용으로 이를 해결 가능.



SHFileOperation

http://msdn.microsoft.com/en-us/library/windows/desktop/bb762164(v=vs.85).aspx

int SHFileOperation(
  _Inout_  LPSHFILEOPSTRUCT lpFileOp 

);


SHFILEOPSTRUCT structure

http://msdn.microsoft.com/en-us/library/windows/desktop/bb759795(v=vs.85).aspx

typedef struct _SHFILEOPSTRUCT { HWND         hwnd; UINT         wFunc; PCZZTSTR     pFrom;    // This string must be double-null terminated.

PCZZTSTR     pTo;      // This string must be double-null terminated.

FILEOP_FLAGS fFlags; BOOL         fAnyOperationsAborted; LPVOID       hNameMappings; PCTSTR       lpszProgressTitle; 

} SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT;


※ 주의

pFrom, pTo 문자열은 반드시 double-null terminated 이어야 한다. 

Although this member is declared as a single null-terminated string, it is actually a buffer that can hold multiple null-delimited file names. Each file name is terminated by a single NULL character. The last file name is terminated with a double NULL character ("\0\0") to indicate the end of the buffer.