정리

boost library build for windows

저장소/VC++

boost, 저도 참 좋아하는데요...

제가 한 번 먹.. 써보도록 하겠습니다.


일단 링크를...

boost : http://www.boost.org/


 windows installer 버전도 있다는 사실!

boostpro.com이 문을 닫아버려 1.51.0 버전까지만 installer가 제공된다.

이전 버전의 다운로드는 요기로~


친절하게 설명된 내용이 있어 알았음.

http://jeffreygoines.tistory.com/14


다음은 windows 환경에서 boost library를 빌드 하는 방법이 설명된 곳

http://anster.egloos.com/2157882




간략히 순서를 정리하자면 다음과 같다.

앵간한거는 걍 include해서 써도 되지만 일부 library는 빌드가 반드시 필요하다고 한다.

어디선가 봤는데 어딘지는 모르겠고.. 영어 해석은 잘 안 되고.. 후..

걍 줴다 만들자.

요 옵션으로 확인 가능하다고 한다.

bjam --show-libraries


1. boost library를 받는다.

windows용은 확장자가 zip인 것을 받아야 한다. zip이 windows용이다. 이 내용 어디서 봤는데.. 어디서 봤더라?

받았으면 압축을 풀고 준비.


2. bjam.exe와 b2.exe를 만들어야 하니까 bootstrap.bat을 실행한다.

bjam은 로 부스트 컴파일을 위한 jamfile parser로 뭐라뭐라 했는데.. 까묵 ㅠㅠ

bjam.exe --help를 치면 도움말 나온다.

b2.exe도 동일하게 나온다. 내부적으로 bjam을 사용하나보다.

웹 문서는 요기

http://www.boost.org/boost-build2/doc/html/index.html

http://www.boost.org/boost-build2/doc/html/bbv2/overview/invocation.html


영어만 보면 어지러워 @_@

복군님 블로그에서 발췌

http://anster.egloos.com/2157882


옵션에 대해 잘 정리된 곳 -> Viper Wiki


bjam 사용법 중 다음이 중요하다.

bjam [options] [properties] [install|stage]


install은 헤더 파일과 빌드된 라이브러리 파일을 설치하고

stage는 빌드된 라이브러리 파일만 설치한다.


install 옵션은 시간도 오래 걸리고 용량도 냠냠 하니까 stage를 권장.

내 스스드는 언제나 용량 부족 ㅠㅠ


3. 급하다! 결론만 간단히!

Visual Studio 컴파일러를 이용해 빌드해야 하니까 원하는 버전의 command prompt를 실행한다.

platform 버전에 맞게~

그담은 boost root 경로로 이동해서 아래와 같이 실행하면 된다.


4. 빌드된 boost library를 보면 이름이 뭐 이따위야 싶은데 네이밍 규칙이 있단다.

http://www.boost.org/doc/libs/1_53_0/more/getting_started/windows.html#library-naming

하.. 영어.. 요것도 퍼옴 ㅠㅠ

원문 출처 : http://anster.egloos.com/2157882



자.. 이제 준비 다 됨.

boost library 사용하려면 include, src 경로를 프로젝트에 포함시키고

빌드된 라이브러리가 필요할 경우엔 stage 경로를 설정해주면 된다.



WinHTTP Equivalents to WinINet Functions

저장소/VC++

일부 시스템에서 WinINet의 InternetOpen API 사용시 Apllication Hang 발생 현상으로 인해서

이것 저것 원인 찾다가 괜찮길래 야무지게 긁어옴. 벗어난 영역은 애교.

문제 원인이나 찾을 것이지... ㅡㅜ




출처 : MSDN (http://msdn.microsoft.com/en-us/library/aa384068(VS.85).aspx)



Porting WinINet Applications to WinHTTP

5 out of 6 rated this helpful Rate this topic

Microsoft Windows HTTP Services (WinHTTP) is targeted at middle-tier and back-end server applications that require access to an HTTP client stack.Microsoft Windows Internet (WinINet) provides an HTTP client stack for client applications, as well as access to the File Transfer Protocol (FTP), SOCKSv4, and Gopher protocols. This overview can help determine whether porting your WinINet applications to WinHTTP would be beneficial. It also describes specific conversion requirements.

Things to Consider Before Porting Your WinINet Application

Consider porting your WinINet application to WinHTTP if your application would benefit from:

  • A server-safe HTTP client stack.
  • Minimized stack usage.
  • The scalability of a server application.
  • Fewer dependencies on platform-related APIs.
  • Support for thread impersonation.
  • A service-friendly HTTP stack.
  • Access to the scriptable WinHttpRequest object.

Do not consider porting your WinINet application to WinHTTP if it must support one or more of the following:

  • The FTP or Gopher protocol from the HTTP stack.
  • Support for SOCKSv4 protocol for communicating with SOCKS proxies.
  • Automatic dial-up services.

If you decide to port your application to WinHTTP, the following sections guide you through the conversion process.

For a sample application for both WinINet and WinHTTP, compare the AsyncDemo sample for WinINet with the AsyncDemo sample for WinHTTP.

WinHTTP Equivalents to WinINet Functions

The following table lists WinINet functions related to the HTTP client stack together with the WinHTTP equivalents.

If your application requires WinINet functions that are not listed, do not port your application to WinHTTP.

WinINet functionWinHTTP equivalentNotable changes
HttpAddRequestHeadersWinHttpAddRequestHeadersNone.
HttpEndRequestWinHttpReceiveResponseThe context value is set with WinHttpSendRequest
or WinHttpSetOption. Request options are set with
 WinHttpOpenRequestWinHttpReceiveResponse
 must be called after sending a request.
HttpOpenRequestWinHttpOpenRequestThe context value is set with WinHttpSendRequest or WinHttpSetOption.
HttpQueryInfoWinHttpQueryHeadersNone.
HttpSendRequestWinHttpSendRequestThe context value can be set with WinHttpSendRequest.
HttpSendRequestExWinHttpSendRequestBuffers cannot be provided.
InternetCanonicalizeUrlNo equivalentURLs are now put in canonical form in WinHttpOpenRequest.
InternetCheckConnectionNo equivalentNot implemented in WinHTTP.
InternetCloseHandleWinHttpCloseHandleClosing a parent handle in WinHTTP does not recursively close child handles.
InternetCombineUrlNo equivalentURLs can be assembled with the WinHttpCreateUrl function.
InternetConfirmZoneCrossingNo equivalentNot implemented in WinHTTP.
InternetConnectWinHttpConnectThe context value is set with WinHttpSendRequest or WinHttpSetOption. Request options are set with WinHttpOpenRequest. User credentials are set withWinHttpSetCredentials.
InternetCrackUrlWinHttpCrackUrlOpposite behavior of the ICU_ESCAPE flag: with
 InternetCrackUrl, this flag causes escape
 sequences (%xx) to be converted to characters,
 but with WinHttpCrackUrl, it causes characters that
 must be escaped from in an HTTP request to be converted
 to escape sequences.
InternetCreateUrlWinHttpCreateUrlNone.
InternetErrorDlgNo equivalentBecause WinHTTP is targeted at server-side applications, it does not implement any user interface.
InternetGetCookieNo equivalentWinHTTP does not persist data between sessions and cannot access WinINet cookies.
InternetOpenWinHttpOpenNone.
InternetOpenUrlWinHttpConnect,
WinHttpOpenRequest,
WinHttpSendRequest,
WinHttpReceiveResponse
This functionality is available in the WinHTTP functions listed.
InternetQueryDataAvailableWinHttpQueryDataAvailableNo reserved parameters.
InternetQueryOptionWinHttpQueryOptionWinHTTP offers a different set of options from WinINet.
 For more information and options offered by WinHTTP, see Option Flags.
InternetReadFileWinHttpReadDataNone.
InternetReadFileExWinHttpReadDataRather than a structure, the buffer is a region of
 memory addressed with a pointer.
InternetSetOptionWinHttpSetOptionNone.
InternetSetStatusCallbackWinHttpSetStatusCallbackFor more information, see "Different Handling of
 Asynchronous Requests" in this topic.
InternetTimeFromSystemTimeWinHttpTimeFromSystemTimeNone.
InternetTimeToSystemTimeWinHttpTimeToSystemTimeNone.
InternetWriteFileWinHttpWriteDataNone.

 

Different Handling of Asynchronous Requests

Be aware that in WinINet and WinHTTP, some functions can complete asynchronous requests either synchronously or asynchronously. Your application must handle either situation. There are significant differences in how WinINet and WinHTTP handle these potentially asynchronous functions.

WinINet

  • Synchronous completion: If a potentially asynchronous WinINet function call completes synchronously, the OUT parameters of the function return the results of the operation. When an error occurs, retrieve the error code by calling GetLastError after the WinINet function call.

  • Asynchronous completion: If a potentially asynchronous function call completes asynchronously, the results of the operation, and any errors, are accessible in the callback function. The callback function is executed on a worker thread, not on the thread that made the initial function call.

In other words, your application must duplicate logic to handle the results of such operations in two places: both immediately after the function call and in the callback function.

WinHTTP simplifies this model by enabling you to implement the operational logic only in the callback function, which receives a completion notification regardless of whether the operation completed synchronously or asynchronously. When asynchronous operation is enabled, the OUT parameters of WinHTTP functions do not return meaningful data and must be set to NULL.

The only significant difference between asynchronous and synchronous completion in WinHTTP, from the application perspective, is in where the callback function is executed.

WinHTTP

  • Synchronous completion: When an operation completes synchronously, the results are returned in a callback function that executes in the same thread as the original function call.

  • Asynchronous completion: When an operation completes asynchronously, the results are returned in a callback function that executes in a worker thread.

Although most errors can also be handled entirely within the callback function, WinHTTP applications must still be prepared for a function to return FALSEbecause of an ERROR_INVALID_PARAMETER or other similar error retrieved by calling GetLastError.

Unlike WinINet, which can execute multiple asynchronous operations simultaneously, WinHTTP enforces a policy of one pending asynchronous operation per request handle. If one operation is pending and another WinHTTP function is called, the second function fails and GetLastError returns ERROR_INVALID_OPERATION.

WinHTTP simplifies this model by enabling you to implement the operational logic only in the callback function, which receives a completion notification regardless of whether the operation completed synchronously or asynchronously. When asynchronous operation is enabled, the OUT parameters of WinHTTP functions do not return meaningful data and must be set to NULL.

Differences in WinHTTP Callback Notifications

The status callback function receives updates on the status of operations through notification flags. In WinHTTP, notifications are selected using thedwNotificationFlags parameter of the WinHttpSetStatusCallback function. Use the WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS flag to be notified of all status updates.

Notifications that indicate a particular operation is complete are called completion notifications, or just completions. In WinINet, each time the callback function receives a completion, the lpvStatusInformation parameter contains an INTERNET_ASYNC_RESULT structure. In WinHTTP, this structure is not available for all completions. It is important to review the reference page for WINHTTP_STATUS_CALLBACK, which contains information about notifications and what type of data can be expected for each.

In WinHTTP, a single completion, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, indicates that an operation failed. All other completions indicate a successful operation.

Both WinINet and WinHTTP use a user-defined context value to pass information from the main thread to the status callback function, which can be executed on a worker thread. In WinINet, the context value used by the status callback function is set by calling one of several functions. In WinHTTP, the context value is set only with WinHttpSendRequest or WinHttpSetOption. Because of this, it is possible in WinHTTP for a notification to occur before a context value is set. If the callback function receives a notification before the context value is set, the application must be prepared to receive NULL in the dwContextparameter of the callback function.

Authentication Differences

In WinINet, user credentials are set by calling the InternetSetOption function, using code similar to that provided in the following code example.

// Use the WinINet InternetSetOption function to set the 
// user credentials to the user name contained in strUsername 
// and the password to the contents of strPassword.
       
InternetSetOption( hRequest, INTERNET_OPTION_PROXY_USERNAME, 
                   strUsername, strlen(strUsername) + 1 );

InternetSetOption( hRequest, INTERNET_OPTION_PROXY_PASSWORD, 
                   strPassword, strlen(strPassword) + 1 );

For compatibility, user credentials can similarly be set in WinHTTP using the WinHttpSetOption function, but this is not recommended because it can pose a security vulnerability.

Instead, when an application receives a 401 status code in WinHTTP, the recommended method of setting credentials is first to identify an authentication scheme using WinHttpQueryAuthSchemes and, second, set the credentials using WinHttpSetCredentials. The following code example shows how to do this.

DWORD dwSupportedSchemes;
DWORD dwPrefered;
DWORD dwTarget;

// Obtain the supported and first schemes.
WinHttpQueryAuthSchemes( hRequest, &dwSupportedSchemes, &dwPrefered, &dwTarget );

// Set the credentials before resending the request.
WinHttpSetCredentials( hRequest, dwTarget, dwPrefered, strUsername, strPassword, NULL );

Because there is no equivalent to InternetErrorDlg in WinHTTP, applications that obtain credentials through a user interface must provide their own interface.

Unlike WinINet, WinHTTP does not cache passwords. Valid user credentials must be supplied for each request.

WinHTTP does not support the Distributed Password Authentication (DPA) scheme supported by WinINet. WinHTTP does, however, support Microsoft Passport 1.4. For more information about using Passport authentication in WinHTTP, see Passport Authentication in WinHTTP.

WinHTTP does not rely on Internet Explorer settings to determine the automatic logon policy. Instead, the auto-logon policy is set with WinHttpSetOption. For more information about authentication in WinHTTP, including the auto-logon policy, see Authentication in WinHTTP.

Differences in Secure HTTP Transactions

In WinINet, initiate a secure session using either HttpOpenRequest or InternetConnect, but in WinHTTP, you must call WinHttpOpenRequest using theWINHTTP_FLAG_SECURE flag.

In a secure HTTP transaction, server certificates can be used to authenticate a server to the client. In WinINet, if a server certificate contains errors,HttpSendRequest fails and provides details about the certificate errors.

In WinHttp, server certificate errors are handled according to the version as follows:

  • Starting with WinHttp 5.1, if a server certificate fails or contains errors, the call to WinHttpSendRequest reports aWINHTTP_CALLBACK_STATUS_SECURE_FAILURE in the callback function. If the error generated by WinHttpSendRequest is ignored, subsequent calls to WinHttpReceiveResponse fail with an ERROR_WINHTTP_OPERATION_CANCELLED error.
  • In WinHTTP 5.0, errors in server certificates do not, by default, cause a request to fail. Instead, the errors are reported in the callback function with theWINHTTP_CALLBACK_STATUS_SECURE_FAILURE notification.

On some earlier platforms, WinINet supported the Private Communication Technology (PCT) and/or Fortezza protocols, although not on Windows XP.

WinHTTP does not support the PCT and Fortezza protocols on any platform, and instead relies on Secure Sockets Layer (SSL) 2.0, SSL 3.0, or Transport Layer Security (TLS) 1.0.

Command Line Build : VCBuild와 MSBuild 그리고 devenv

저장소/VC++

VS2008에서 C/C++ 프로젝트를 빌드할 때 vcbuild.exe를 사용했었는데 이거 VS2010부터 없어졌다 한다. 맘이 아푸다 ㅠㅠ

대신 MSBuild에서 C/C++ 프로젝트를 빌드 할 수 있다고 한다.

MSBuild는 C:\Windows\Microsoft.NET\Framework 아래 있다. 한참 찾았다.

근데 난 devenv.exe로 빌드하는 것도 편한 것 같다.

devenv에서 msbuild를 이용해 빌드한다고 하는데 devenv의 command line 명령어가 눈에 잘 들어온다.


명령어 구성은 다음과 같으니 종종 보자.




Visual Studio 원격 디버깅(Remote Debugger)

저장소/VC++

Visual Studio 원격 디버깅 방법



정리는 조금 천천히




VirtualBox로의 원격 디버깅을 하기 위한 네트워크 설정은 다음과 같이 한다.


1. VirtualBox Manager의 메뉴 중 '파일'->'환경설정'->'네트워크' 에서 '호스트 전용 네트워크 정보' 확인

'어댑터'와 'DHCP 서버' 설정의 IP 대역을 확인한다.


2. OS 이미지의 설정의 네트워크 항목에서 어댑터1은 NAT로, 어댑터2를 추가(네트워크 어댑터 사용하기 체크)하여 호스트 전용 어댑터로 설정한 뒤 구동한다.


3. Remote Debugger를 구동할 때 command line 명령을 이용하여 호스트명을 명시적으로 지정한다.

호스트 전용 어댑터의 IP를 설정하면 된다. 명령은 다음과 같다.


msvsmon.exe /hostname 192.168.56.101 /noauth /anyuser


이렇게 하면 디버깅 대상 PC의 설정은 끝이다.

다음은 Visual Studio를 이용해 디버깅을 할 PC의 설정이다....


역시 정리는 나중에.. 귀찮;

네트워크 프로그래밍 할 때 종종 보는 에러들 정리

저장소/VC++

IOCP를 사용한 네트워크 프로그래밍에서 종종 보이는 에러들, 자주 보이는 순서대로 정리.

수신 대기 중 발생되는 에러 원인 찾다가 잘 정리된 내용 복사복사.


내용 출처 :

네이버, 구글 검색

내가 테스트 해본 것도 포함

http://javawork.egloos.com/2265358

http://cafe.naver.com/ongameserver/3758

http://newworlds.tistory.com/1178

http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNo=20&no=345120&ref=336795

http://blog.naver.com/ddinggill/100110486640


http://coderoid.tistory.com/46

http://www.gpgstudy.com/forum/viewtopic.php?p=41368

http://mindsteeper.tistory.com/188




ERROR_SEM_TIMEOUT (121)

The semaphore timeout period has expired.

장비(방화벽 또는 라우터) 이상 또는 제한으로 인한 네트워크 단절(랜선을 뽑는 경우도 포함)이 발생했을 때

(어느쪽? 서버? 클라?)


ERROR_NETNAME_DELETED (64)

The specified network name is no longer available.

보통 IOCP에서 소켓 끊어짐의 상징은 0 byte read 입니다.

0 byte read가 통보되는 시점은 상대방 소켓에서 closesocket() 혹은 shutdown() 함수를 호출한 시점입니다.

즉, 상대방이 closesocket() 혹은 shutdown() 을 호출하지 않고 종료해버리면 일반적으로 0 byte read는 발생하지 않습니다.

이렇게 0 byte read가 발생하지 않은 상태에서 read() 혹은 write()를 시도하면 상대는 이미 종료 되었으므로

ERROR_NETNAME_DELETED 에러가 나게 됩니다. 이러한 경우를 우아한 종료와는 반대되는 개념으로 HardClose라고 합니다.


WSAENOTSOCK (10054)

An operation was attempted on something that is not a socket.

지정한 소켓은 정상 적이지 않습니다(INVALID_SOCKET). 별도의 종료처리없이 소켓을 닫으면 나옵니다. 


ERROR_IO_PENDING (997)

Overlapped I/O operation is in progress.

이건 더 수신(송신)할 내용이 있을 때 확인되는 값으로 에러로 보기 어렵다.

수신중이었다면 마저 수신처리 하면 된다.

데이터 수신량 확인 시 0 byte면 종료로 봐야하나.

아닌가? 모르겠다. 이건 볼 때마다 모르겠다. 뭐야 이거;; 무서워

허나 GetQueuedCompletionStatus 호출 후 결과는 성공인데 transferred bytes가 0 일 경우에도 이 에러가 확인 된다.

임의로 0 byte를 보내지 않는 이상 보편적으로 transferred bytes가 0 이면 연결이 끊긴 것으로 간주한다.

이럴 땐 transferred bytes의 값을 보고 판단하는게 맞는 것 같다.


ERROR_OPERATION_ABORTED (995)

The I/O operation has been aborted because of either a thread exit or an application request.

1. 작업이 취소된 사례. CreateIoCompletionPort에 추가한 핸들(소켓)이 닫혔을 때.

 클라이언트가 연결된 상태에서 서버가 먼저 종료하면 발생.(server socket이 close되어서)

2. 동시에 송수신할 때

 CreateIoCompletionPort에 핸들(소켓)을 추가하기 전에

 WSADuplicateSocket 이나 DuplicateHandle 를 이용해 핸들을 복사하여 분리해서 추가해주면 된다고 한다.(정말?? 진짜??)




TortoiseSVN(Diff, Log, Blame)과 Visual Studio 통합 방법

저장소/VC++

요기서 퍼왔어요~

http://tortoisesvn.net/visualstudio.html


AnkhSVN이나 VisualSVN을 설치해서 써도 좋지만,

TortoiseSVN의 Diff, Log, Blame 기능만 사용해도 충분하다면 다음과 같이 설정한다.



If you're using Visual Studio, you can integrate TortoiseSVN commands to various context menus. Of course, there are Subversion plugins for Visual Studio like AnkhSVN or VisualSVN, with the latter already using TortoiseSVN for many of its UI. Those plugins also have the advantage that when you do refactoring, they automatically record the renames and moves in SVN.

But if you're using one of the free versions of Visual Studio, you can not use those plugins. And sometimes it's still nice to have some of the TortoiseSVN commands available from Visual Studio directly, even if you have such a plugin installed.

The first step is to add the TortoiseSVN commands as external tools, under the menu TOOLS->External Tools....


  한국어 버전 ->  

Add the name of the command, the path to TortoiseProc.exe and then the parameters for the command.

Use the VS variables wherever needed. Since I add my commands to the context menu of the open file tab, here's the parameters I used:

  • /command:blame /path:"$(ItemPath)" /line:$(CurLine)
  • /command:diff /path:"$(ItemPath)"
  • /command:log /path:"$(ItemPath)"

Notice the /line: parameter: this will make TortoiseBlame automatically scroll to the same line the cursor is located in the opened file in Visual Studio.

Now to add those new commands to the file tab context menu, go to TOOLS->Customize..., select the Commands tab, click the radio button Context menu and then select Other Context Menus | Easy MDI Document Window.


 

 한국어 버전 ->  

Then click the Add command... button:


  한국어 버전 ->  

Now you have to select the commands. Problem is that the custom commands are not shown with their title but only as External Command X with X being the number of the external command.

In my case, the commands were number 9-11, you might have to do some trial-and-error here. Just add the commands you think are the ones you added and then check if the right ones show up in the context menu.

음... 외부  도구에서 추가한 기능의 이름이 안 보이고 그냥 '외부 명령 XX' 요렇게 보이는 것에 주의 필요합니다.

대충 제일 아래쪽부터 순서대로 찍으면 될듯... ^^;

And this is how the context menu of the open file tab looks like:


  한국어 버전 ->  

Verifying the Signature of a PE File : 코드사인 검증

저장소/VC++


MSDN : Example C Program: Verifying the Signature of a PE File

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




gtest VS2012에서 에러 - error C2977: 'std::tuple' : too many template arguments

저장소/VC++

좋은 정리 감사해서 긁어왔습니다.


원문 출처 : http://kbdyj.tistory.com/30



2010에서 GTEST를 쓰는 프로젝트를 2012로 옮겨와 빌드하니 에러가 발생.


error C2977: 'std::tuple' : too many template arguments 라는 내용인데 2012에서 아직 variadic template를 지원하지 않는다는게 원인인 것 같다.


이 방법을 해결하는 방법이 두가지 인데


첫째 옵션에서 C/C++>Preprocessor>Preprocessor Definitions에서

GTEST_HAS_TR1_TUPLE=0

을 주어 빌드하거나


두번째로 Configuration Properties>General>Platform Toolset을 Visual Studio 2010(v100)으로 맞춰놓고 빌드하는 것이다.


첫번째 방법으로 했다가 GTEST 자체를 2010으로 빌드한 것을 가져다 썼더니 링크에러가 나서 두번째 방법으로 해결하였다. (GTEST를 다시 빌드하기 귀찮아서)



warning LNK4099

저장소/VC++

정리 잘 되어있는 블로그

http://altprog.com/blog/2054



다음 내용은 gpg 링크가 종종 깨지거나 없어지는듯...은 핑계고 링크 따라가기 귀찮아서 긁어왔다.

출처 : http://www.gpgstudy.com/forum/viewtopic.php?p=91716



  

글쓴이메시지
idlast



가입: 2007년 2월 12일
올린 글: 17

올리기warning LNK4099 이 경고 메시지는 무엇인가요?올려짐: 2007-02-21 10:59
인용과 함께 답변 이 게시물을 del.icio.us에 추가

warning LNK4099: '~.pdb' PDB를 '~.lib' 또는 '~.pdb'에서 찾을 수 없습니다. 디버그 정보가 없는 것처럼 개체를 링크합니다. 
이런 경고가 떠서 컴파일 할때마다 신경이 쓰여요.. ㅠㅠ 
왜 이런 에러가 뜨는 거죠? 
떠도 괜찮은 건지.. 
_________________
(만지작 거리는 단계)
위로


Rica



가입: 2004년 8월 9일
올린 글: 86

올리기올려짐: 2007-02-21 11:05
인용과 함께 답변 이 게시물을 del.icio.us에 추가

디버그 모드에서 디버그 정보를 포함하지 않은 라이브러리를 함께 링크하려고 하면 아마 저럴 겁니다. 
아니면 라이브러리 빌드한 경로가 잘못되었거나.. 

라이브러리 안으로 들어가서 디버깅하시지 않는다면 신경 안 쓰셔도 될 거라고 생각합니다.
위로


zupet



가입: 2003년 5월 13일
올린 글: 2761
소속: EA Seoul Studio

올리기Re: warning LNK4099 이 경고 메시지는 무엇인가요?올려짐: 2007-02-21 13:16
인용과 함께 답변 이 게시물을 del.icio.us에 추가

idlast 씀:
warning LNK4099: '~.pdb' PDB를 '~.lib' 또는 '~.pdb'에서 찾을 수 없습니다. 디버그 정보가 없는 것처럼 개체를 링크합니다. 
이런 경고가 떠서 컴파일 할때마다 신경이 쓰여요.. ㅠㅠ 
왜 이런 에러가 뜨는 거죠? 
떠도 괜찮은 건지.. 


올바른 PDB 정보를 찾지 못할때 그렇습니다. LIB를 만들때 프로그램 디버깅 정보(심볼 및 기타 Debug & Continue 정보)가 LIB 파일에 들어가는 경우와 LIB 파일과 같이 생성되는 PDB 파일에 포함되는 경우가 있습니다. 

LIB에 같이 포함되게 하기 위해서는 디버깅 정보를 /Z7 으로 변경하고 C/C++ Command Line 옵션에 /Yd를 수동으로 입력해주는 것으로 해결이 됩니다. 일단 PDB가 생성되기 시작하면 /Z7을 쓰더라도 PDB안에 디버깅 정보가 몰려가기때문에(이건 M$가 신경을 좀 덜써준듯) 이렇게 사용할 경우 LIB 프로젝트에 pch 생성을 사용해서는 안됩니다. pch를 생성하기 위해선 PDB 파일이 만들어져야 하는데 PDB 파일이 있으면 디버깅 정보가 생성되면서 LIB(내의 obj)안에 포함되어지지 않고 무조건 PDB 파일에 기록되게 되어 있습니다. 

Edit & Continue 가 지원되도록 디버깅 정보 레벨을 올리면서 디버깅 정보를 배포하기 위해선 컴파일시 생성되는 PDB 파일을 LIB와 같이 위치 시켜야 하는데 LIB 프로젝트는 EXE와 달리 최종 PDB를 모아주지 않기 때문에 /Release/vc70.pdb, /Debug/vc70.pdb 파일들을 사용해야 합니다. 이름이 보기 좋지 않고 obj 파일 내에 이 파일에 대한 절대 경로가 포함되기 때문에 같은 폴더에 ~~~.lib, vc70.pdb 를 같이 넣어주거나 C++ 프로젝트 셋팅을 바꿔서 vc70.pdb를 ~~~.pdb 식으로 이름을 변경해주도록 설정해주는게 좋습니다.
위로


비회원
손님





올리기흠.. 에러를 단순히 무시하는 방법은 없나요?올려짐: 2007-02-27 10:41
인용과 함께 답변 이 게시물을 del.icio.us에 추가

디버그 버전에서 디버깅 정보가 없는 lib (외부 lib 등) 를 사용할때도 
자꾸 4099 워닝이 떠서 은근히 거슬리는데 그냥 무시해버리는 방법은 없을까요? 

googling 을 하면 link 커맨드라인에 "/IGNORE:4099" 의 식으로 주면 해결된다고 하는데, 
(undocumented option 이라고 하는군요) 
저렇게 해도 해결이 되지 않네요.
위로


liteplayer



가입: 2003년 10월 30일
올린 글: 43

올리기올려짐: 2007-02-27 10:55
인용과 함께 답변 이 게시물을 del.icio.us에 추가

안녕하세요? 

라이브러리 링크를 소스에 명시할 경우(#prgma comment\(lib,""\)) 에는 
#pragma warning(disable: xxxx) 이 되는걸로 알고있습니다.
위로


비회원
손님





올리기올려짐: 2007-02-27 11:27
인용과 함께 답변 이 게시물을 del.icio.us에 추가

답변 갑사합니다. 

#pragma warning(disable: ####) 는 컴파일러 워닝만 무시해주는데, 
링커의 워닝을 무시하고 싶습니다. 

구글링 해서 나온 방법대로 
추가 command line 옵션에 /IGNORE:4099 -IGNORE:4099 를 붙여봐도 되지 않고 
혹시나 하는 마음에 

#pragma comment(lib, "/IGNORE:4099") 

를 해봐도 되지 않는군요.
위로


비회원
손님





올리기올려짐: 2007-12-13 16:10
인용과 함께 답변 이 게시물을 del.icio.us에 추가

같은문제로 고민했습니다만, 친절히도 

Thanks for the error report - this isn't the first time we've had this request. Unfortunately, we just don't have the resources to address the issue during this product cycle. We will try to revisit the issue in future product cycles. 

요런답변을 MS로 부터 얻을수 있었습니다. -_- 

http://connect.micr...px?FeedbackID=176188
위로


milennium9



가입: 2007년 2월 1일
올린 글: 71

올리기올려짐: 2007-12-20 17:38
인용과 함께 답변 이 게시물을 del.icio.us에 추가

위와 같은 버그가 있을때!! 해당 PDB 파일에 접근을 못할경우가 대다수 더군요. 그래서 저는 임시로 PDB 파일의 이름을 바꿔줍니다. 
이상하게 지우지는 못하면서 이름은 바꿔지더군요. 
가끔 정상종료를 못했을 때 다음번 빌드에서 PDB파일에 접근하지 못하는 버그 같은데요. 일단 이름 바꿔주면 괜찮습니다.
위로


log4cxx - Visual Studio 빌드

저장소/VC++

Visual Studio 2012에서 log4cxx를 빌드할 때 한 번에 쉽게 되지가 않더라.. ㅠㅠ
좋은 내용이 있어서 담아본다. 아래 내용 참고.




log4cxx
log4j 를 본따 c++ 버전으로 만든 ASF(http://apache.org/)의 OSS.
(log4j 메뉴얼을 참조해도 된다. 거의 비슷..)

로그 레벨 : ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF



log4cxx 빌드 (Visual Studio 2008)


1. Download Installation File
Apache log4cxx  [ver 0.10.0]
Apache Portable Runtime (APR) [ver 1.4.2]
Apache Portable Runtime-util (APR-util) [ver 1.3.10]
GNU Sed [ver 4.2]

2. Installation
1. Decompress APR, APR-util, log4cxx File in same folder
ex) 아래와 같이 폴더 이름 변경 필수
c:\work\log4cxx\apr
c:\work\log4cxx\apr-util
c:\work\log4cxx\log4cxx
2. Install GNS sed 
Run "sed-4.2-1-setup.exe"
Add environment variable %PATH% : "C:\Program Files\GnuWin32\bin" 
3. In "cmd", move "C:\work\log4cxx\log4cxx" folder.
Run "configure.bat"
Run "configure-aprutil.bat"
4. Compile "C:\work\log4cxx\log4cxx\projects\log4cxx.dsw"
Result : log4cxx.dll, log4cxx.lib
("C:\work\log4cxx\log4cxx\projects\Debug or Release")
5. include file
C:\work\log4cxx\log4cxx\src\main\include
3. Visual Studio 2008 에서 사용하기 위한 설정 configuration
in Project Property Pages
"C/C++ > General > Additional Include Directories" : C:\work\log4cxx\log4cxx\src\main\include
"C/C++ > Linker > Additional Library Directories" : C:\work\log4cxx\log4cxx\projects\Debug
In .cpp
#pragma warning ( disable: 4231 ) 
#pragma comment(lib, "log4cxx.lib")
Log4cxx 용 (properties 설정 파일)


[log4cxx.conf]
# root logger setting
#log4j.rootLogger=DEBUG, console, filelog, chainsaw, rollingfile
log4j.rootLogger=DEBUG,filelog, console

# using console appender
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{ISO8601} [%-5p] %c(%L) : %m%n
#log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p (%F:%L) - %m%n


# using rolling file appender
log4j.appender.rollingfile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingfile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingfile.File=Rlog.txt
log4j.appender.rollingfile.layout.ConversionPattern=[%d] [%-5p] (%L) - %m%n
log4j.appender.rollingfile.MaxFileSize=500MB
log4j.appender.rollingfile.MaxBackupIndex=3

# using filelog appender
log4j.appender.filelog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.filelog.layout=org.apache.log4j.PatternLayout
log4j.appender.filelog.layout.ConversionPattern=[%d] [%-5p] (%L) - %m%n
log4j.appender.filelog.Append=true
log4j.appender.filelog.DatePattern='.'yyyy-MM-dd
log4j.appender.filelog.File=testlog.log

# using chainsaw appender
log4j.appender.chainsaw=org.apache.log4j.net.SocketAppender
log4j.appender.chainsaw.remoteHost=localhost
log4j.appender.chainsaw.port=4445
log4j.appender.chainsaw.locationInfo=true 

[.cpp]
#include <windows.h>
#include <string>
#include <iostream>
using namespace std;

#pragma warning ( disable: 4231 ) 
#include <log4cxx/logger.h>
#include <log4cxx/basicconfigurator.h>
#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/helpers/exception.h>

#pragma comment(lib, "log4cxx.lib")
using namespace log4cxx;
using namespace log4cxx::helpers;

int main(void)
{
try
{
string filePath = "log4cxx.conf";
PropertyConfigurator::configure(File(filePath));

LoggerPtr rootlog = Logger::getRootLogger();
LoggerPtr log = Logger::getLogger("");

LOG4CXX_FATAL(log, "fatal output...");
LOG4CXX_ERROR(log, "error output...");
LOG4CXX_WARN (log, "warn  output...");
LOG4CXX_INFO (log, "info  output...");
LOG4CXX_DEBUG(log, "debug output...");
}
catch(const Exception& e) {
cout << "[ERROR] configure()\n" << e.what() << endl;
}

return EXIT_SUCCESS;
} 

#pragma warning ( disable: 4231 )
컴파일시 다음 warning 보기 싫어서 넣음. c:\work\log4cxx\log4cxx\src\main\include\log4cxx\spi\configurator.h(57) : warning C4231: nonstandard extension used : 'extern' before template explicit instantiation 



Log4cxx - 사용 (xml 설정 파일)

[log4cxx.xml]
<?xml version="1.0" encoding="UTF-8" ?>
<log4j:configuration debug="false" xmlns:log4j="http://jakarta.apache.org/log4j/">

  <appender name="logConsoleAppender" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{ISO8601} [%-5p] [%c:%L] %m%n"/>
    </layout>
  </appender>
  <appender name="logRollingFileAppender" class="org.apache.log4j.RollingFileAppender">
    <param name="file" value="TestRolling500MB.log" />
    <param name="append" value="true" />
    <param name="MaxFileSize" value="500MB" />
    <param name="MaxBackupIndex" value="3" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{ISO8601} [%-5p] [%c:%L] %m%n"/>
    </layout>
  </appender>
aadafasf
  <appender name="logTimeRollingFileAppender" class="org.apache.log4j.rolling.RollingFileAppender">
    <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
      <param name="fileNamePattern" value="TestTimeRolling.%d{yyyy-MM-dd}.log"/> <!--Dailly-->
    </rollingPolicy>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{ISO8601} [%-5p] [%c:%L] %m%n"/>
    </layout>
  </appender>
  
  <root>
    <level value="debug" />
    <appender-ref ref="logConsoleAppender"/>
    <appender-ref ref="logRollingFileAppender"/>
    <appender-ref ref="logTimeRollingFileAppender"/>
  </root>

  <category name="testCategory" >
    <level value ="info" />
    <appender-ref ref="logTimeRollingFileAppender"/>
  </category>

</log4j:configuration> 

[.cpp]
#include <windows.h>
#include <string>
#include <iostream>
using namespace std;

#pragma warning ( disable: 4231 ) 
#include <log4cxx/logger.h>
#include <log4cxx/basicconfigurator.h>
#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/helpers/exception.h>
#include <log4cxx/xml/domconfigurator.h>

#pragma comment(lib, "log4cxx.lib")
using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::xml;

int main(void)
{
try
{
string filePath = "log4cxx.conf";
DOMConfigurator::configure(filePath);

LoggerPtr rootlog = Logger::getRootLogger();
LoggerPtr log = Logger::getLogger("");

LOG4CXX_FATAL(log, "fatal output...");
LOG4CXX_ERROR(log, "error output...");
LOG4CXX_WARN (log, "warn  output...");
LOG4CXX_INFO (log, "info  output...");
LOG4CXX_DEBUG(log, "debug output...");
}
catch(const Exception& e) {
cout << "[ERROR] configure()\n" << e.what() << endl;
}

return EXIT_SUCCESS;
} 

**. log4cxx 사용법 reference
http://joygram.org/wiki/doku.php?id=log4cxx log4cxx 파일 안의 test 소스  



Log4cxx - 개인용 샘플

[사용]
#include "LoggerManager.h"

int main(void)
{
wstring xmlfilepath = _T("log4cxx.xml");
try
{
CLoggerManager::initialize(xmlfilepath);
}
catch (const Exception& e)
{
cout << "[ERROR] " << e.what() << endl;
}

CLogger logger = CLoggerManager::getRootLogger();
if (logger.isDebugEnabled())
logger.debug(wstring(_T("hi")));

return 0;
}
 




Visual Studio 2010 에서 log4cxx 빌드

설치는 위에서 설명한 "log4cxx 빌드 (Visual Studio 2008)" 의 "1. Download Installation File" 와 "2. Installation" 까지 진행 후
log4cxx 솔루션 파일(log4cxx/projects/log4cxx.dsw) 을 Visual Studio 2010으로 열면 프로젝트 자동변환을 진행하고
아래 데로 변경하면 됩니다. (일단 32bit 기준)
설치 바이너리 버전 : apache-log4cxx-0.10.0.zip, apr-1.4.5-win32-src.zip, apr-util-1.3.12-win32-src.zip, sed-4.2.1-setup.exe
1. log4cxx 프로젝트
에러 유형 1. LOG4CXX_LIST_DEF 정의 관련..
log4cxx\src\main\include\log4cxx/helpers/simpledateformat.h(78): error C2252: 템플릿은 네임스페이스 범위에서만 명시적으로 인스턴스화할 수 있습니다.
LOG4CXX_LIST_DEF(..) 를 class 정의 밖으로 옮긴다. (namespace 정의 안, class 정의 밖)
LOG4CXX_LIST_DEF(ConnectionList, Connection); 의 경우 윗줄의
typedef log4cxx::helpers::SocketPtr Connection; 도 같이 옮긴다.
에러 유형 2. KeySet namespace 관련..
..\src\main\cpp\propertiespatternconverter.cpp(62): error C2039: 'KeySet' : 'log4cxx::spi::LoggingEvent'의 멤버가 아닙니다.
LoggingEvent::KeySet keySet 를 KeySet keySet으로 변경. (namespace 제거)
에러 유형 3. iterator 관련..
..\src\main\cpp\propertiespatternconverter.cpp(64): error C2065: 'const_iterator' : 선언되지 않은 식별자입니다.
#include <iterator> 추가
에러 유형 4. apr, aprutil 링크 에러
library 참조 수동 설정 필요.
아래와 같이 Debug, Release 에 대해 수동 설정. Debug는 LibD, Release는 LibR 폴더에 생성됨.
"log4cxx > 프로젝트 속성 > 링커 > 일반 > 추가 라이브러리 디렉토리 " 추가 (Release 모드는 LibD)
..\..\apr\LibD
..\..\apr-util\LibD
..\..\apr-util\xml\expat\lib\LibD
"log4cxx > 프로젝트 속성 > 링커 > 입력 > 추가 종속성 " 추가
apr.lib
aprutil.lib
xml.lib
2. apr 프로젝트 
D:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(1151,5): warning MSB8012: TargetPath(E:\SRC\NewBaseApp\WISM\Library\log4cxx\apr\.\LibR\apr.lib)이(가) Library의 OutputFile 속성 값(E:\SRC\NewBaseApp\WISM\Library\log4cxx\apr\LibR\apr-1.lib)과 일치하지 않습니다. 이로 인해 프로젝트가 잘못 빌드될 수 있습니다. 이를 수정하려면 $(OutDir), $(TargetName) 및 $(TargetExt) 속성 값이 %(Lib.OutputFile)에 지정된 값과 일치해야 합니다.
D:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(1153,5): warning MSB8012: TargetName(apr)이(가) Library의 OutputFile 속성 값(apr-1)과 일치하지 않습니다. 이로 인해 프로젝트가 잘못 빌드될 수 있습니다. 이를 수정하려면 $(OutDir), $(TargetName) 및 $(TargetExt) 속성 값이 %(Lib.OutputFile)에 지정된 값과 일치해야 합니다.
apr 프로젝트 속성의 "라이브러리 관리자 > 일반 > 출력 파일" 을 LibR\apr.lib 로 변경.
("일반>대상이름"과 일치 시키기. 디버그 모드는 LibD\apr.lib)

3. aprutil 프로젝트
D:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(1151,5): warning MSB8012: TargetPath(..\log4cxx\apr-util\.\LibR\aprutil.lib)이(가) Library의 OutputFile 속성 값(E:\SRC\NewBaseApp\WISM\Library\log4cxx\apr-util\LibR\aprutil-1.lib)과 일치하지 않습니다. 이로 인해 프로젝트가 잘못 빌드될 수 있습니다. 이를 수정하려면 $(OutDir), $(TargetName) 및 $(TargetExt) 속성 값이 %(Lib.OutputFile)에 지정된 값과 일치해야 합니다.
D:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(1153,5): warning MSB8012: TargetName(aprutil)이(가) Library의 OutputFile 속성 값(aprutil-1)과 일치하지 않습니다. 이로 인해 프로젝트가 잘못 빌드될 수 있습니다. 이를 수정하려면 $(OutDir), $(TargetName) 및 $(TargetExt) 속성 값이 %(Lib.OutputFile)에 지정된 값과 일치해야 합니다.
aprutil 프로젝트 속성의 "라이브러리 관리자 > 일반 > 출력 파일" 을 LibR\aprutil.lib 로 변경.
("일반>대상이름"과 일치 시키기. 디버그 모드는 LibD\aprutil.lib)

4. apr, aprutil, xml 빌드 후 log4cxx 프로젝트 빌드
log4cxx\projects\Debug 에 log4cxx.lib, log4cxx.dll 파일 생성



log4cxx 64 bit은 컴파일 구성 추가 후 빌드하면 된다는 것 같은데 아직 안해봤습니다.