- 환경 
 1. A.exe를 VC++에서 디버그 모드로 실행
 2. B.dll의 특정함수를 디버깅 하고 싶음. 그런데, A.exe와 B.dll은 하나의 solution에 들어있는 project가 아님.

- 준비물
 1. A.exe의 소스코드
 2. B.dll의 소스코드
 3. B.pdb 파일 <- 디버그 모드로 빌드했음을 의미.

- 방법
 1. 위 1번 실시
 2. A.exe 실행중 사용되는 B.dll이 있는 폴더에. B.pdb(디버그 정보파일)을 넣음
 3. A.exe code에서 B.dll의 함수를 call하는 곳에 breakpoint BP#1를 걸면
 4. 그 breakpoint BP#1에서 B.dll의 소스코드를 묻는 팝업창이 뜸
    소스코드를 찾아서 선택.
   (이 팝업창의 맨 위쪽에 Original location이 있어서, 소스코드 있는 폴더를 찾기 쉬움)
 5. B.dll의 소스코드가 VC++에 보이면서 디버깅이 가능해짐.
 6. B.dll의 소스코드의 필요한 위치에 breakpoint BP#2를 설정하면, 향후 편리.


* VC+2013에서 실테스트 함.

Posted by 세모아
,


출처: http://jacking.tistory.com/792


세미나에서 제가 살짝 정신줄을 놓아서(? -_-;;) 이 부분 설명이 미흡했는데

int* p = nullptr;
p = new int[200];

에서 p의 첫번째 위치에서 11번째만 보고 싶은 경우는
(p+10)



11번째에서 5개만 보고 싶은 경우는
(p+10), 5




Posted by 세모아
,

[VC++] error LNK2019: unresolved external symbol  발생시의 해결책 :

 


해결책 :

  • Linker - Input - Additional Library Directories에 lib 폴더를 지정하고,
    Linker - Input - Additional Dependencies에  abc.lib 을 추가
    또는
    Linker - Input - Additional Library Directories에 lib 폴더를 지정하고,
    cpp 코드 상단에 #pragma comment(lib, "Ws2_32.lib"를 추가
  • 32 and 64 bit versions of the libraries을 맞춤 
    ( 32bit 프로젝트에 64bit lib을 넣어서 발생하는 경우도 있음) //16.8.11

  

cf.

Possible reasons:

  • the sdl.lib and sdlmain.lib settings are not added to dependency list
  • their location was not added to the list of directories where the linker looks
  • you have mismatched 32 and 64 bit versions of the libraries.


Posted by 세모아
,

#include <cmath>

<math.h>도 같이 include되며 이 안에 'M_PI' 라는 pi 값이 저장되어 있다. (3.14159265358979323846)






from: http://genepart2.tistory.com/6


※레퍼런스를 참조하는 수고를 덜기 위해서 자주 쓰이는 함수들을 간단하게 정리해놓은 것이다.

(따라서 없는 것도 많다.)

설명된 함수들은 함수의 원형이며 사용시에는 함수명(변수)로 사용하면 된다. ex) abs(x);

헤더파일은 "math.h" 이다


1. 절대 값 함수

  int abs(int x) - int x의 절대값을 반환

  long labs(long x) - long x의 절대값을 반환

  double fabs(double x) - double x의 절대값을 반환


2. 삼각함수

  ※삼각함수들은 인수는 각도가 아닌 라디안 값이며 각도를 라디안 값으로 바꾸는 공식은 "각도*π/180" 이다.

     역함수들은 인자값으로 -1 ~ 1사이의 값만 가질 수 있다.

  double acos(double x) - cos의 역함수로써 cos(x) = a라면 acos(a) = x가 된다

  double asin(double x) - sin의 역함수

  double atan(double x) - tan의 역함수

  double atan2(double x, double y) - atan(x/y)와 같은 기능의 함수. y가 0에 가까울수록 atan보다 정확하다.

  double cos(double x) - 삼각함수 cos(x)의 값을 구한다.

  double sin(double x) - 삼각함수 sin(x)의 값을 구한다.

  double tan(double x) - 삼각함수 tan(x)의 값을 구한다.

  double cosh(double x) - 쌍곡선 cosh(x)의 값을 구한다.

  double sinh(double x) - 쌍곡선 sinh(x)의 값을 구한다.

  double tanh(double x) - 쌍곡선 tanh(x)의 값을 구한다.


3. 정수화 함수

  double ceil(double x) - double x의 소수 값 이하 올림

  double floor(double x) - double x의 소수 값 이하 버림


4. 지수함수

  double exp(double n) - eⁿ의 값을 구한다. 자연상수 e = 2.71828182845904523536...

  double pow(double x, double y) - x의 y승을 구한다.

  double sqrt(double x) - x의 제곱근을 구한다.

  double log(double x) - 밑이 e값인 logx값을 구한다.

  double log10(double x) - 밑이 10인 logx값을 구한다.


5. 기타함수

  double fmod(double x, double y) - x/y의 나머지 값을 구한다.

  double ldexp(double x, int y) - x*(2의 y승) 값을 구한다.

  double modf(double x, double *y) - x를 정수부와 소수부로 분리해서 소수부는 반환, 정수부는 y에 저장한다.


Posted by 세모아
,

출처: http://blog.bsk.im/2013/10/24/visual-studio-console-remained/



다양한 언어를 지원하면서 강력한 디버깅 기능을 가지고 있는 비주얼 스튜디오는 이클립스와 더불어 가장 많이 사용되는 IDE(통합 개발환경, Integrated Developing Environment)입니다. 아직도 대다수의 사람들이 프로그래밍을 배울 때 C나 C++로 시작합니다. 가장 기본이 되면서 중요하기 때문이죠. 많은 대학교에서 C를 기초과목으로 가르치고 있는 것도 비슷한 이유일 것입니다. Visual Studio는 C와 C++, C#과 닷넷 등에 대한 강력한 개발환경을 지원하는데다, DreamSpark 프로그램을 통해 교육기관이나 학생들에게 무료로 배포되기 때문에 많은 사랑을 받고 있죠.

프로그래밍을 처음 배우시는 분들이나 간단한 프로그램을 만드는 경우 보통 과거 도스 환경을 연상케 하는, “까만 바탕에 하얀 글씨” 인터페이스인 콘솔 응용 프로그램을 만들게 됩니다.

일반적으로 코딩을 하는 경우 먼저 코드를 작성 한 뒤, 프로그램을 실행 해 자신의 코드가 잘 동작하는 지 확인하고 오류를 잡기 위한 ‘디버깅’과정을 반복하게 됩니다.

Visual Studio에서는 Ctrl + F5키를 이용해 프로그램을 실행, 즉 “디버깅 하지 않고 시작(Start without debugging)”할 수 있습니다. 그러면 명령 프롬프트가 실행되면서 창에서 결과값을 확인할 수 있죠. 그런데 프로그램이 종료되면서 이 콘솔 창이 사라지게 되면 프로그램이 종료되기 전까지의 결과를 확인할 수 없게 됩니다. 그래서 아래 그림처럼 Visual Studio는 자동으로 프로그램이 종료되기 직전에프로그램을 멈추어 줍니다.

비주얼 스튜디오에서 종료 직전에 프로그램을 자동으로 멈춘 모습

즉, 비주얼 스튜디오가 소스코드에 다음과 같이 system(“pause”)를 자동으로 추가해 주는 것입니다.

#include <stdio.h>
int main(...) {  
    //작성한 코드
    system("pause");
    return 0;
}

하지만, 프로젝트 생성 시 콘솔 응용 프로그램으로 생성하지 않는 경우 Build 할 때의 flag가 달라져 Ctrl + F5를 이용해 실행하는 경우에도 프로그램이 종료되면 자동으로 콘솔 창이 꺼지는 경우가 있습니다.

이런 경우 위 코드처럼 소스코드 마지막에 system(“pause”)를 추가하거나 다음과 같이 프로젝트 속성을 바꿔 주면 됩니다.

  1. 메뉴의 [프로젝트(Project)] – ['프로젝트 이름' 속성(Properties)]으로 들어갑니다.

  2. 왼쪽의 [구성 속성(Configuration Properties)] – [링커(Linker)]에서 [시스템(System)]을 선택하고, 오른쪽의 [하위 시스템(Subsystem)]에서 콘솔 Console (/SUBSYSTEM:CONSOLE)을 선택합니다.

  3. 이제 Ctrl + F5를 눌러 프로그램을 실행하면 종료 후 창이 사라지지 않는 것을 확인할 수 있습니다.

    비주얼 스튜디오에서 종료 직전에 프로그램을 자동으로 멈춘 모습


'Programming > C++' 카테고리의 다른 글

C 표준 수학함수  (0) 2016.06.18
[펌] FFMPEG: Can not free AVPacket when decode H264 stream?  (0) 2016.03.27
av_free_packet 예제들  (0) 2016.03.27
Posted by 세모아
,

AVPacket 해제에 대한 글


출처 :  http://stackoverflow.com/questions/26090992/ffmpeg-can-not-free-avpacket-when-decode-h264-stream





av_free_packet will clear your packet data, the same pointer that was allocated inside av_read_frame. But you changed it in packet.data += bytesDecoded; => crash.

Several advices:

  • No need to call av_init_packet if the first use of your packet is av_read_frame (it is done inside this function). But if you keep your code, you need it in order to initialize packet.size to 0 (tested, but not initialized the first time)

  • Call av_free_packet each time you are done with the packet data, only when the decode is successful. In your code, it means you must call it after avcodec_decode_video2, even if the frame is not finished.

  • Once your packed is decoded (i.e. avcodec_decode_video2 is ok, no matter if frameFinished is true or false), you can free it. No need to keep it and change data pointer. The process is "read packet, decode it, free it. read next packet, decode it, free it.". (Note that this does not apply to audio packets).

I suggest simplify your main loop by something like (read first, decode after):

while(true)
{
    // Step 1: Read packet
    while(true)
    {
        av_read_frame(pFormatCtx, &packet);

        // todo: Error handling

        if(packet.stream_index != videoStreamIndex)
        {
            av_free_packet(&packet);
        }
        else
        {
            break;
        }
    } while (packet.stream_index != videoStreamIndex);

    // Step 2/3: Decode and free
    avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
    av_free_packet(&packet);

    // todo: Error handling and checking frameFinished if needed
    // Of course, if you need to use the packet now, move the av_free_packet() after this
}


Posted by 세모아
,



할일: ManagedDecoder.cpp에서, decodingRTSP에서 2종류의 avpacket을 한번만 선언해서 사용하기




pkt을 한번만 선언해서 av_free_packet(.)해도 계속 사용하는 사례

2015년에 작성된 H264 codec test 샘플코드임.


https://ffmpeg.org/doxygen/2.8/api-h264-test_8c_source.html#l00032


106  i = 0;
107  av_init_packet(&pkt);
108  do {
109  if (!end_of_stream)
110  if (av_read_frame(fmt_ctx, &pkt) < 0)
111  end_of_stream = 1;
112  if (end_of_stream) {
113  pkt.data = NULL;
114  pkt.size = 0;
115  }
116  if (pkt.stream_index == video_stream || end_of_stream) {
117  got_frame = 0;
118  if (pkt.pts == AV_NOPTS_VALUE)
119  pkt.pts = pkt.dts = i;
120  result = avcodec_decode_video2(ctx, fr, &got_frame, &pkt);
121  if (result < 0) {
122  av_log(NULL, AV_LOG_ERROR, "Error decoding frame\n");
123  return result;
124  }
125  if (got_frame) {
126  number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size,
127  (const uint8_t* const *)fr->data, (const int*) fr->linesize,
128  ctx->pix_fmt, ctx->width, ctx->height, 1);
129  if (number_of_written_bytes < 0) {
130  av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n");
131  return number_of_written_bytes;
132  }
133  printf("%d, %10"PRId64", %10"PRId64", %8"PRId64", %8d, 0x%08lx\n", video_stream,
135  number_of_written_bytes, av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes));
136  }
137  av_free_packet(&pkt);
138  av_init_packet(&pkt);
139  }
140  i++;
141  } while (!end_of_stream || got_frame);







https://ffmpeg.org/doxygen/2.8/decoding__encoding_8c_source.html#l00347



Posted by 세모아
,

출처: http://bluexmas.tistory.com/273



ffmpeg - rtmp sample 테스트

Programming/C++ 2012.05.25 17:19 Posted by 파란크리스마스

출처 : RTMPDump
Compiling RTMPdump on Max OS X
Compiling FFmpeg 0.9 with libRTMP and libmp3lame for Intel and ARM CPUs
Compiling FFMPEG 0.6 with RTMP Support for OSX 
ffmpeg ndk 빌드 #2 ffmpeg 옵션별 빌드
best-video-player
Fix rtmp double cflags in pkgconfig module

다운로드

RTMPDump 에서 rtmpdump-2.3.tgz 파일 다운로드

압축풀기

tar xvfz rtmpdump-2.3.gz

ffmpeg 폴더로 이동 시키기

mv rtmpdump-2.3/librtmp ffmpeg-0.10.3

rtmp 라이브러리 컴파일, 설치

cd ffmpeg-0.10.3/librtmp
make SYS=linux install
echo 'export PKG_CONFIG_PATH=/lib/pkgconfig:/usr/local/lib/pkgconfig' | tee -a ~/.bashrc

configure

config.sh 파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export TMPDIR=c:/ffmpegtmp
 
./configure --disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-devices \
--disable-filters \
--disable-yasm \
--enable-network \
--enable-protocol=tcp \
--enable-demuxer=rtsp \
--enable-decoder=h264 \
--enable-librtmp

./config.sh

make

testmain.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdio.h>
#include <stdlib.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
  
  
int main(int argc, char** argv) {
  
    AVFormatContext* context = avformat_alloc_context();
    int video_stream_index;
  
    av_register_all();
    avcodec_register_all();
    avformat_network_init();
 
    //if(avformat_open_input(&context, "rtsp://192.168.0.40/vod/mp4:sample.mp4",NULL,NULL) != 0){
    //if(avformat_open_input(&context, "rtmp://192.168.0.40/vod/sample.mp4",NULL,NULL) != 0){      
    //if(avformat_open_input(&context, "d:\\windows\\b.mp4",NULL,NULL) != 0){
  
    //open rtsp
    if(avformat_open_input(&context, "rtmp://192.168.0.40/vod/sample.mp4",NULL,NULL) != 0){        
        return EXIT_FAILURE;
    }
  
    if(avformat_find_stream_info(context,NULL) < 0){
        return EXIT_FAILURE;
    }
  
    //search video stream
    int i;
    for(i =0;i<context->nb_streams;i++){
        if(context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
            video_stream_index = i;
    }
  
    AVPacket packet;
    av_init_packet(&packet);
  
    //open output file
    AVOutputFormat* fmt = av_guess_format(NULL,"test2.avi",NULL);
    AVFormatContext* oc = avformat_alloc_context();
    oc->oformat = fmt;
    avio_open2(&oc->pb, "test.avi", AVIO_FLAG_WRITE,NULL,NULL);
  
    AVStream* stream=NULL;
    int cnt = 0;
    //start reading packets from stream and write them to file
  
    av_read_play(context);//play RTSP
    while(av_read_frame(context,&packet)>=0 && cnt <100){//read 100 frames
        if(packet.stream_index == video_stream_index){//packet is video               
            if(stream == NULL){//create stream in file
                stream = avformat_new_stream(oc,context->streams[video_stream_index]->codec->codec);
                avcodec_copy_context(stream->codec,context->streams[video_stream_index]->codec);
                stream->sample_aspect_ratio = context->streams[video_stream_index]->codec->sample_aspect_ratio;
                avformat_write_header(oc,NULL);
            }
            packet.stream_index = stream->id;
  
            av_write_frame(oc,&packet);
            cnt++;
        }
        av_free_packet(&packet);
        av_init_packet(&packet);
    }
    av_read_pause(context);
    av_write_trailer(oc);
    avio_close(oc->pb);
    avformat_free_context(oc);
  
    return (EXIT_SUCCESS);
}

Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
TARGET = hello3
 
FFMPEGDIR = /home/bluesanta/ffmpeg-0.10.3
 
LIBDIR = /lib
 
CC  = gcc
AR  = ar
LD  = ld
NM  = nm
RANLIB  = ranlib
STRIP = strip
 
INCLUDE = -I.. -I.
 
CFLAGS = -Wall
LDFFMPEG = -L$(FFMPEGDIR)/libavformat -L$(FFMPEGDIR)/libavcodec -L$(FFMPEGDIR)/libavutil -L$(FFMPEGDIR)/librtmp
LDFLAGS = -L$(LIBDIR) $(LDFFMPEG) -lavformat -lavcodec -lavutil -lrtmp -lkernel32 -lcygwin -lm -lgcc -lc -lssl -lz -lcrypto
 
# application file
APPSOURCES = testmain.c
APPOBJS = $(APPSOURCES:.c=.o)
 
# define the rule
.SUFFIXES:.c .o
 
.c.o:
    @echo Compiling: $<
    $(CC) -c $(CFLAGS)  $(INCLUDE) -o $@ $<
 
all: app
 
app: $(APPOBJS)
    @echo Linking: $(TARGET)
    $(CC) -o $(TARGET) $(APPOBJS) $(LDFLAGS)
    $(STRIP) -s $(TARGET)
 
clean:
    @rm -vf $(APPOBJS) $(TARGET)

컴파일, 실행

 


'Programming > C++' 카테고리의 다른 글

av_free_packet 예제들  (0) 2016.03.27
[펌] How to: Debug from a DLL Project  (0) 2016.03.26
[펌] pragma에 관한 사용법  (0) 2016.03.07
Posted by 세모아
,


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



Visual Studio 2013 대상


How to: Debug from a DLL Project


To specify the calling application in a C++ project

  1. In Solution Explorer, select the DLL project.

  2. On the View menu, choose Property Pages.

  3. In the ProjectProperty Pages window, in the Configuration drop-down list, choose Debug.

  4. Open the Configuration Properties folder, and select the Debugging category.

  5. In the Debugger to launch list, choose Local Windows Debugger or Remote Windows Debugger.

  6. In the Command or Remote Command box, click the drop-down arrow, and select Browse from the list to locate the application.Alternatively, type the path and name of the application.

  7. Type any necessary program arguments in the Command Arguments box.

To specify the calling application in a C# or Visual Basic project

  1. In Solution Explorer, select the DLL project.

  2. On the View menu, choose Property Pages.

  3. In the ProjectProperty Pages window, in the Configuration drop-down list, choose Debug.

  4. Click the Debug tab.

  5. You can start the application by either doing the following:

    1. Set the Start Action to Start external program.

    2. In the Start external program box, click the ellipsis button to browse for the application.

    3. Enter any necessary program arguments in the Command Line Arguments box.

  6. Or, you can invoke an application at a URL. (You might want to do this if you are debugging a managed DLL used by a local ASP.NET application.)

    1. Under Start Action, select the Start browser in URL: radio button.

    2. In the adjoining text box, type the URL.

To start debugging from the DLL project

  1. In Solution Explorer, select the DLL project.

  2. Set breakpoints as needed.

  3. Enter the name and location of the calling application in the ProjectProperty Pages dialog box or window. If the application is a console application, fill in the command line arguments, if it is necessary.


Posted by 세모아
,

아래 내용중에서 필요한 것은,


#pragma comment()

이 중 가장 대표적인 사용법은 명시적인 라이브러리의 링크이다.

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

와 같이 사용하여 해당 라이브러리를 링크시켜 준다.
 여러사람이 같이 수행하는 프로젝트의 경우 이와 같은 방법을 사용하여 lib를 링크하는 것이 라이브러리가 링크되어있다는 사실을 알기에도 좋고 굳이 주석다라 설명할 필요도 없어 좋지 않나 싶다. (있다는 사실은 알지만 아직 프로젝트 수행중 실제로 사용해 본적은 없음)

굳이 project settings에서 link tab에 있는 input에 .lib file을 쓰지 않고 #pragma comment ( lib, "xxx.lib" ) 라고 써도 된다는 거죠..



My)

아래그림과 같이 Linker의 Additional Library Directories에  lib파일이 있는 경로에 포함시키고,

cpp파일에 #pragma comment(lib, "avformat.lib") 

을 기록한다.




참고 : http://oojjrs.tistory.com/35 (#pragma comment(lib, file) 에 임의의 상대경로 입력하기)





출처: http://iprinceps.egloos.com/1334766

매번 매번 사용해도 헷갈리는 pragma의 용법에 대해 모아 총정리 하였다.

#pragma는 define 이나 include와 같이 #으로 시작하는 전처리구문(precompiler)의 하나이다.
 컴파일러에 종속적인 구문이라 컴파일러가 변경되었을 경우 제대로된 동작을 보장하지 못하므로 프로젝트 진행중에 서로 다른 컴파일러를 사용한다면 사용하지 않음이 바람직 하겠다.
 - 대신 대체하는 문법을 사용해야 되겠다.

#pragma once
 이것은 "컴파일러에게 한번만 컴파일해!" 라고 명령한다.
 헤더의 중복을 막아준다.
 무슨말인가 하면
a.h를 구현한 a.cpp, a.h는 독립적이다.(include가 없다.)
b.h를 구현한 b.cpp, c.h, a.h순서로 include
c.h를 구현한 c.cpp, a.h를 include

 컴파일하면 b.h에서 c.h를 포함시키라고 되어있네? 하고 c.h에 들어가고 어? a.h를 포함하라고 그러네? 이러고 a.h를 포함한 c.h가 b.h로 돌아온다 그리고 a.h를 포함하라는 명령을 받고 a.h를 추가하다보면 같은 변수와 함수선언이 되어있다. 에러에러~
 같은 선언이 두 번 반복되니 당연히 충돌이 난다. 컴파일러가 똑똑하여 단순히 경고 처리만 해주고 알아서 하나로 종합해줄 수도 있지만 대부분의 기본적인 컴파일러는 이건 아니잖아~ 한다.

 이럴 때 써주는 것이다. pragma once
 이는 c기본문법을 사용하여 구현할 수 있다.

#ifdef _MYCOMPILECK
#define _MYCOMPILECK
// 헤더 파일의 내용 선언
#endif



#pragma comment()
기본적인 pragma comment()의 형식은 다음과 같다.

#pragma comment( comment-type, ["comment string"] )

[] 안의 구문은 comment-type에 따라 필요할 경우 사용하는 것이다.
comment type에는 compiler, exestr, lib, linker, user 등이 올 수 있다.

#pragma comment( linker, "/subsystem:windows" )
#pragma comment( linker, "/subsystem:console" )

linker 를 사용하면 프로젝트를 console application인지 win32 application인지 명시해줄 수 있다.

또한 섹션의 설정을 할 수 있다.

#pragme comment( linker, "SECTION:.SHAREDATA,RWS" )

#pragma data_seg("SHAREDATA") 와 함께 사용하여 공유 메모리를 생성한다.
위의 명령어 대신 def 파일 안에 아래와 같이 해주어도 된다.

SECTIONS
 SHAREDATA READ WRITE SHARED


이 중 가장 대표적인 사용법은 명시적인 라이브러리의 링크이다.

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

와 같이 사용하여 해당 라이브러리를 링크시켜 준다.
 여러사람이 같이 수행하는 프로젝트의 경우 이와 같은 방법을 사용하여 lib를 링크하는 것이 라이브러리가 링크되어있다는 사실을 알기에도 좋고 굳이 주석다라 설명할 필요도 없어 좋지 않나 싶다. (있다는 사실은 알지만 아직 프로젝트 수행중 실제로 사용해 본적은 없음)



#pragma data_seg()
pragma data_seg()의 형식은 다음과 같다.

#pragma data_seg( ["section-name"[, "section-class"] ] )

[]는 사용하지 않아도 된다는 의미이다.

#pragma data_seg( "SHAREDATA" )
 int x;
 char y;
#pragma data_seg()

 DLL 파일을 만들어보면서 제일 많이 사용해 보았고 가장 헷갈려 했던 부분이기도 하다.
 DLL의 데이터 공유를 하기 위해 사용한다.
 공유할 섹션을 만드는 것이다. 위의 명령어는 필수적으로 위에서 사용된 두 가지중 한가지 방법과 함께 사용 되어야 한다.

#pragme comment( linker, "SECTION:.SHAREDATA,RWS" )
SECTIONS
 SHAREDATA READ WRITE SHARED

 둘 다 해당 SECTION(SHAREDATA)의 허용 범위(?속성?)를 설정하는 것이다. READ, WRITE, SHARED 세 가지를 쓴다는 의미~
 해당 사항에 대해 msdn에서 자세한 정보를 발견하지 못해 적지 못하였다(검색능력의 부족!!)
 이제 변수 x와 y는 해당 dll을 사용하는 외부 파일과 같이 공유할 수 있는 변수가 되었다.(외부에서 접근 가능하게 되었다.)

 이렇게 공유하는 변수는 물론 new로 메모리를 할당한 변수도 공유 가능하다.
 특히 new 나 memalloc(이건 아직 미확인이지만 같은 메모리 할당이므로 가능할 것으로 본다)으로 메모리할당한 변수들은 dll외부에서도 해제(delete) 가능하다.



#pragma warning
특정 경고를 끄고 싶을 때 사용한다.
비쥬얼 스튜디오의 버전이 다르기 때문에 뜨는 경고는 더더욱이 귀찮은 존재이다.(하지만 수정해서 손해볼 것은 없다. 그것이 곧 버그로 이어질 수 있기 때문이다. 특히 형변환의 경우 강제 캐스팅하여 확실히 명시해주는 것이 좋다. 일부러 그 값을 떼어낸다는 프로그래머의 의지를 컴파일러에게 보여주자. 부지런할수록 후에 손이 가는 일이 적어진다. 노력하자~)

형식은 이와 같다.

#pragma warning( warning-specifier : warning-number-list [; warning-specifier : warning-number-list...] )
#pragma warning( push[ ,n ] )
#pragma warning( pop )

실제 사용은 아래와 같이 한다.

#pragma warning( disable:4996 )




#pragma message()
컴파일 중에 메세지를 뿌려준다.
 말이 필요없다-.-/

#pragma message("merong")

Takes from: http://mayu.tistory.com/8

선행처리기중의 하나인 pragma에 관한 사용법을 정리하여 올립니다.
문법은 다음과 같습니다.

 

#pragma directive-name


#pragma는 이것을 지원하는 다른 compiler에서 방해가 없이 C++ Builder에서 원하는
지시어를 정의할 수 있도록 해줍니다. 만일 지시명을 인식하지 못한다면 에러 또는
경고 메세지를 수반하지 않고서 #pragma의 지시를 무시하게 됩니다.

Borland C++ Builder에서 지원하는 #pragma지시어는 모두 18가지가 있습니다.
이제부터 그것들을 하나 하나 살펴보기로 하겠습니다.

1. #pragma anon_struct
    . 사용법 
      #pragma anon_struct on
      #pragma anon_struct off
    . Class에 익명의 구조체를 포함하여 compile하는것을 허락할 것인지를
      지시합니다. 익명이란 tag를 갖지 않는다는것을 의미합니다.
    ex)
    #pragma anon_struct on
    struct S {
       int i;
       struct {  // 익명구조체를 포함한다.
          int   j ;
          float x ;
       };
       class {  // 익명 클래스를 포함한다.
       public:
          long double ld;
       };
    S() { i = 1; j = 2; x = 3.3; ld = 12345.5;}
    };
    #pragma anon_struct off

    void main() {
       S mystruct;
       mystruct.x = 1.2;  // 포함된 data에 값을 할당한다.
   }

//--------------------------------------------------------------------------
2. #pragma argsused
    . argsused 프라그마는 함수 정의 사이에서만 허용되고 바로 다음 함수에만
      영향을 미치며 경고 메세지를 disable시킵니다.
      이 pragma를 사용하지 않은 경우 사용되지 않은 argument가 있으면
      "Parameter name is never used in function func-name"
      라는 경고 메세지를 표시하게 됩니다.
    ex)
    #pragma argsused
    void __fastcall TImageForm::FileEditKeyPress(TObject* Sender, Char &Key)
    {     if (Key == 0x13) {
             FileListBox1->ApplyFilePath(FileEdit->Text);
             Key = 0x0;
          }
    }
    위의 예에서는 함수내에서 Sender라는 인수가 사용되지 않았지만 경고 메세지가
    표시되지 않습니다.

//--------------------------------------------------------------------------
3. #pragma codeseg
    . 사용법
      #pragma codeseg <seg_name> <"seg_class"> <group>
    . codeseg 프라그마는 함수들을 위치시킬 group, class 또는 segment의 이름을
      줄수 있도록 지시합니다. 만일 option없이 사용하였다면 함수의 배치를 위해서
      default code segment가 사용되어질것입니다. 결국 이 pragma를 사용하지 않는
      경우와 동일한 결과를 가져옵니다.

//--------------------------------------------------------------------------

4. #pragma comment
    . 사용법 
      #pragma comment (comment type, "string")
    . comment 프라그마는 출력되어지는 file에 주석을 기록시킬것을 지시합니다.
      comment type에 올수 있는 값들은 다음중의 하나가 될것입니다.
      * exestr
        linker가 ".OBJ" file에 string을 기록합니다. 이렇게 기록된 string은
        실행파일내부에 기록되어지며, 이것은 결코 메모리로 load되지 않습니다.
        하지만 적당한 파일 검색 유틸리티를 사용하여 실행파일에서 string을
        찾아볼 수 있습니다.
      * lib
        ".OBJ" file에 주석의 내용을 기록합니다.
        library에 새로운 module을 추가하는 경우 에만 comment 프라그마를 사용하여
        linker에게 결과 file에 명시할 수 있도록 지시할 수 있습니다. 다시 말하면
        기존에 작성되어진 module에는 comment 프라그마를 사용하여 string을 추가
        시킬수 없습니다. 새롭게 library를 작성한다면 예외일 수 있겠지요.
        linker는 최종의 library에서 string에 명시된 library module 이름을 포함
        합니다. 여러개의 module들도 이름지어질 수 있으며 이름을 만들기 위하여
        linke되어집니다.

        예) comment ( lib, * ) : comment로 사용할 수 있는 명령은 여러 개 있는데, 그중 가장 대표적인 것이 lib 으로, 해당 라이브러리를 링크시켜준다 .

             즉, 지정된 라이브러리 화일을 포함하여 컴파일한다. 프로젝트 설정에 라이브러리를 포함하는 것과 같다.

        예2) comment( lib, "ws2_32" ) 
              이것은, 컴파일시 ws2_32.lib 파일을 링크하라는 명령입니다. 보통 Visual studio같은
              IDE 개발환경에서는, 프로젝트 셋팅에서 해주지만, 혹 그런부분을 빼먹거나 환경이
              바뀔때를 대비해서 이렇게 해두면 편하죠.

        예3) #pragma comment( "comment-type" [, commentstring] )

              comment type에는 compiler, exestr, lib, linker, user 등이 올 수 있습니다.

              그 중 질문에서의 lib는 library file을 지정하는 것이라고 생각하시면 됩니다. comment string이라는 부분에는 file의 이름이나 path를 넣으시면 됩니다. ".lib" file 아시죠?

               그러니까 굳이 project settings에서 link tab에 있는 input에 .lib file을 쓰지 않고 #pragma comment ( lib, "xxx.lib" ) 라고 써도 된다는 거죠..


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

//--------------------------------------------------------------------------

 

5. #pragma exit
    . 사용법
      #pragma startup function-name <priority>
      #pragma exit function-name <priority>
    . 이들 두 프라그마는 프로그램이 프로그램 시동시(main이 호출되기 전) 호출
      되어야 할 함수와 프로그램 탈출(프로그램이 _exit를 통해 종료하기 바로 전)
      을 명시할 수 있도록 합니다. 명시된 function-name은 반드시 인수를 취하지
      않고 void를 return하는 미리 선언된 함수여야합니다. 다시 말하면 다음과
      같이 선언될 수 있습니다.
      void func (void);
      priority는 반드시 64-255의 범위 내에 있는 정수여야하며 최상의 우선권은
      0입니다. 0-63사이의 priority는 C library에서 사용하므로 사용자가 이를
      사용해서는 안됩니다. 최상위 우선권을 가진 함수는 시동시에 맨 먼저 호출
      되고 탈출시에 맨 마지막으로 호출됩니다. 우선권을 명시해 주지 않을 경우
      기본적으로 100의 우선권을 갖게 됩니다. pragma startup 또는 exit에 사용된
      함수명은 반드시 프라그마 라인에 도달하기 전에 정의(또는 선언)되어야함에
      주의하십시요.
    ex)
      #include <stdio.h>
      void startFunc(void)
      {
          printf("Startup Function.\n");
      }
      #pragma startup startFunc 64 //우선권 64로 시동시에 맨 먼저 호출됩니다.

      void exit Func(void)
      {
          pirntf("Wrapping up execution.\n");
      }
      #pragma exit exitFunc //기본적으로 우선권이 100으로 지정됩니다.

      void main(void)
      {
          printf("This is main.\n");
      }

//--------------------------------------------------------------------------

6. #pragma hdrfile
    . 사용법
      #pragma hdrfile "filename.CSM"
    . 이 지시어는 프리컴파일된 헤더를 저장할 파일의 이름을 설정합니다. IDE
      프로젝트를 위한 디폴트 파일명은 <projectname>.CSM이고 command line용
      으로는 BC32DEF.CSM이라는 이름을 갖습니다.  프리컴파일된 헤더를 사용하지
      않으면 이 지시어는 효력이 없으며 명령라인 컴파일러 옵션 -H=filename 또는
      프리 컴파일된 헤더를 사용하면 프리 컴파일된 헤더를 저장하기 위해 사용되는
      파일명을 변경할 수 있습니다.
      명령라인 옵션은 다음과 같습니다.
      * 프리컴파일드 헤더를 사용하는 경우
        -H=filename
      * 프리컴파일드 헤더를 사용은 하지만 새로운 프리컴파일드 헤더파일을
        변환하지 않는 경우
        -Hu
      * 프리컴파일드 헤더를 사용하지 않거나 새로운 프리컴파일드 헤더파일을
        변환하지 않는 경우. (기본값)
        -H-

//--------------------------------------------------------------------------

7. #pragma hdrstop
    . 사용법
      #pragma hdrstop
    . 이 지시어는 프리컴파일에 적합한 헤더 파일의 목록을 종료시키는데, 이것을
      사용하면 프리컴파일된 헤더가 사용하는 디스크 공간의 양을 줄일 수 있습니다.
      프리컴파일드 헤더파일은 #pragma hdrstop이 선언되기 전에 #include를
      사용하여 포함된 헤더파일들을 동일하게 프로젝트 내의 source들간에 공유시킬
      수 있습니다. 그러므로 #pragma hdrstop전에 일반적인 헤더파일들을 포함하면
      최상의 콤파일러의 성능을 얻을 수 있습니다. 확실하게 #pragma hdrstop 전에
      #include를 사용한다면 모든 source file들에게 동일하게 적용되거나 아주
      조그마한 변화만이 있을 것입니다. IDE 환경에서는 강화된 프리컴파일드 헤더의
      성능을 가지는 코드로 변환합니다. 예를 들자면 다음의 New Application의 소스
      파일인 "Unit1.cpp"는 다음과 같이 될것입니다.

      #include <vcl.h> // 일반적인 헤더파일
      #pragma hdrstop  // 헤더파일의 리스트는 여기서 끝난다.

      #include "Unit1.h" // 헤더파일의 명시
      //....
      이 pragma 지시어는 오직 source file에서만 사용하며, 헤더파일에서 사용했다
      면 아무런 효과도 없을 것입니다.

//--------------------------------------------------------------------------

8. #pragma inline
    . 사용법
      #pragma inline
    . 이 지시어는 명령 라인 콤파일러 옵션 -B 또는 IDE의 인라인 옵션과 동일
      합니다. 이것은 컴파일러에게 프로그램 내에 인라인 어셈블리 언어 코드가
      있음을 알려줍니다. 컴파일러는 #pragma inline을 만날때 -B옵션을 사용하여
      스스로 재시동하므로 이 지시어는 파일의 상단에 배치되는 것이 최선입니다.
      실제로 -B옵션과 #pragma inline을 모두 off시켜둘 수 있습니다. 그러면
      컴파일러는 asm문을 만나자마자 스스로 재시동합니다. 이 옵션과 지시어의
      목적은 컴파일 시간을 다소 절약하는 것입니다.

//--------------------------------------------------------------------------

9. #pragma intrinsic
    . 사용법
      #pragma intrinsic [-]function-name
    . #pragma intrinsic를 사용하면 함수의 inline화를 위해 command-line 스위치나
      IDE의 옵션이 무시되어집니다.  intrinsic함수를 인라인화할 때는 그 함수를
      사용하기 전에 반드시 그것을 위한 원형을 포함시켜야만 합니다. 이것은
      인라인화 할 때 컴파일러가 인라인화한 함수를 내부적으로 인식하는 함수로
      개명하는 매크로를 실제로 생성하기 때문입니다. 가령 strcpy 함수를 인라인
      화 하기 위하여 다음과 같은 문장을 사용하였다면
      #pragma intrinsic strcpy
      컴파일러는 다음과 같은 매크로를 생성합니다.
      #define strcpy __strcpy__
      컴파일러는 두 선행 밑줄과 두 후미 밑줄을 사용하여 함수 호출을 인식하고
      그 함수의 원형을 내부적으로 저장해 둔 원형과 부합시키려 합니다. 그러므로
      원형을 공급하지 않거나 공급한 원형이 콤파일러 내부의 원형과 부합되지 않을
      경우, 콤파일러는 그 함수를 인라인화 하려는 시도를 불식시키고 에러를
      발생시킵니다. 이 프라그마 사용의 궁극적인 목적은 함수 호출에 대한
      오버헤드를 줄위기 위한것입니다. 함수호출은 빨라지겠지만 그만큼 크기는
      증가하게 될것입니다.
      ex)
      #pragma intrinsic strcpy
      #pragma intrinsic -strcpy

//--------------------------------------------------------------------------

10.#pragma link
    . 사용법
      #pragma link "[path]modulename[.ext]"
    . 이 지시어는 실행화일에 파일을 링크시킬것을 링커에세 지시합니다.
      기본적으로 링커는 -L옵션으로 지정된 패스와 로칼 디렉토리에서 modulename을
      찾습니다. path 아규먼트를 이용하여 디렉토리를 지정할 수도 있습니다. 또한
      링커는 확장자를 ".obj"를 기본으로 간주합니다.

//--------------------------------------------------------------------------

11. #pragma message

     컴파일 도중에 지정된 내용을 VC의 아웃풋 윈도우에 출력시켜 준다. 컴파일시 특정 문장을 표시
    . 사용법
      #pragma message ("text" ["text"["text" ...]])
      #pragma message text
    . #pragma message는 프로그램 코드 내에서 사용자 정의 메세지를 명시합니다.
      첫번째 형식은 하나 이상의 스트링 상수들로 구성된 문장을 필요로 하고
      메세지는 괄호안에 싸여있어야만 합니다.(이 형식은 MSC와 호환됩니다.)
      두번째 형식은 경고 메세지의 문장을 위해 #pragma에 연속되는 문장을
      사용합니다. #pragma의 두가지 형태와 함께 다른 메크로의 참조는 메세지가
      디스플레이 되기전에 확장되어집니다.  사용자 정의 메세지가 디스플레이
      되는것은 기본치이며 명령 라인 옵션의 Show Warnings를 사용하여
      on/off 시킬 수 있습니다. 이 옵션은 콤파일러의 -wmsg에 해당합니다.

    ex)
      // msacm.h
      #if defined(UNICODE) && !defined(_UNICODE)
      #ifndef RC_INVOKED
      #pragma message("MSACM.H: defining _UNICODE
                       because application defined UNICODE")
      #endif
      #define _UNICODE
      #endif

      // ustring.h
      #pragma message osl/ustring.h has been replaced by winsys/string.h
      #include <winsys/string.h>

//--------------------------------------------------------------------------

12.#pragma obsolete
    . 사용법
      #pragma obsolete identifier
    . #pragma obsolete 프로그램 코드에서 pragma의 선언 이후에 마주치게 되는
      identifier의 첫번째 사용에 대해서 경고를 발생합니다. 경고는 identifier를
      쓸모없는 상태로 만듭니다.
    ex)
    // io.h
    #if !defined(RC_INVOKED)

    /* Obsolete functions */
    #pragma obsolete _chmod
    #pragma obsolete _close
    #pragma obsolete _creat
    #pragma obsolete _open
    #pragma obsolete _read
    #pragma obsolete _write

    /* restore default packing */
    #pragma pack(pop)

    #if defined(__STDC__)
    #pragma warn .nak
    #endif

    #endif  /* !RC_INVOKED */

//--------------------------------------------------------------------------

13.#pragma option
    . 사용법
      #pragma option options
      #pragma option push options
      #pragma option pop
    . #pragma option은 프로그램 원시 코드 내에 명령라인 옵션을 포함시키고자
      할 때 사용하며 push 또는 pop 옵션과 함께 사용되어질 수 있습니다.
      options는 임의의 명령라인 옵션(단, 아래에 수록된 것은 제외합니다.)이며
      하나의 지시어 내에서 여러개의 option들을 나타낼 수 있습니다.
      예를 들자면 다음과 같습니다.

      #pragma option -C
      #pragma option -C -A

      toggle option(-a, -K같은)은 comman line에서 on/off될수 있습니다.
      이들 toggle option들은 option 다음에 마침표를 두면 그 명령라인, 구성 파일,
      옵션 메뉴 설정값에 대해 옵션을 리털할 수 있으며 이를 이용하면 정확한
      설정값을 기억하지 않고도(혹은 알 필요가 없거나) 옵션을 임시로 변경했다가
      다시 그것을 디폴트로 복귀시킬 수 있습니다.

      pragma optino에 포함하여 나타날 수 없는 옵션들은 다음과 같습니다.
      -B   -c   -dname
      -Dname=string   -efilename   -E
      -Fx  -h   -lfilename
      -lexset   -M   -o
      -P   -Q   -S
      -T   -Uname   -V
      -X   -Y
      다음의 경우에 #pragmas, #indluces, #define과 약간의 #ifs를 사용할 수
      있습니다.
      * #if, #ifdef, #ifndef 또는 #elif지시어 내에서 두 밑줄로 시작하는 매크로명
        (그리고 그에 따른 내장 매크로도 가능합니다.)의 사용 전.
      * 첫번째 실재 token이 발생하기 전(첫번째 C 또는 C++ 선언문)

      특정 명령 라인 옵션은 이들 사건 앞의 #pragma option 내에서만 나타날 수
      있는데 그러한 option들은 다음과 같습니다.
      -Efilename        -f      -i#
      -m*   -npath   -ofilename
      -u   -W   -z

      다른 option들은 어디서나 변경될 수 있는데 다음 option들은 함수 또는 대상
      선언문 사이에서 변경될 경우 컴파일러에만 영향을 미칩니다.
      -1        -h      -r
      -2   -k   -rd
      -a   -N   -v
      -ff  -O   -y
      -G   -p   -Z

      다음의 option들은 언제든지 변경될 수 있으며 즉시 영향을 미칠 수 있습니다.
      -A   -gn   -zE
      -b   -jn   -zF
      -C   -K   -zH
      -d   -wxxx
      이들 option들은 그 명령 라인 상태로 재설정하기 위해 점(.)앞에 추가로
      나타날 수 있습니다.

      push 또는 pop을 사용한 #pragma option
      18:41, 21 February 2007 (PST)18:41, 21 February 2007 (PST)18:41, 21 February 2007 (PST)18:41, 21 February 2007 (PST)18:41, 21 February 2007 (PST)18:41, 21 February 2007 (PST)18:41, 21 February 2007 (PST)~~
      또한 콤파일러 지시어들을 쉽게 변경할 수 있도록 push 그리고 pop 아규먼트들
      과 함께 #pragma option 지시어를 사용할 수도 있습니다.

      잠재적으로 많은 컴파일러 옵션과 경고들을 변경하는 파일들을 포함하기 위해
      #pragma option push를 사용할 수 있고, #pragma option pop은 단일 문장으로서
      이전의 상태를 되돌려준다. 예를 들자면 다음과 같다.

      #pragma option push
      #include <theworld.h>
      #pragma option pop
      #include "mystuff.h"

      #pragma option push 지시어는 첫번째로 모든 콤파일러 옵션들과 경고 설정들을
      스택에 push한 후에 다른 옵션들이 존재한다면 이를 처리한다. 다음의 예는
      #pragma option push가 옵션들을 사용하거나 혹은 그렇지 않을수 있음을
      보여줍니다.

      #pragma option push -C -A
      #pragma option push

      #pragma option pop directive은 스택으로부터 옵션들과 경고들의 마지막 설정
      을 pop함으로서 컴파일러 옵션과 경고들을 변경합니다. 만일 스택이 비어있고
      option pop과 일치하는 option push가 없으며 아무것도 발생하지 않은경우
      경고가 주어집니다. 다음은 빈 스택에대해서 경고를 발생시킵니다.

      #pragma option push
      #pragma option pop
      #pragma option pop      /* 경고가 발생합니다.

      권장하지는 않지만 지시어를 사용하여 이 경고를 off시킬 수 있습니다.
      #pragma warn -nop.

      만일 pop의 다음에 어떤 옵셥들을 명시할려고 한다면 에러가 발생하게되며
      pragma option pop 다음에는 어떤것도 허락하지 않습니다. 예를 들면, 다음은
      에러를 발생합니다.

      #pragma option pop -C         /* ERROR
      만일 push된 옵션들의 스택이 파일의 시작과 마지막이 동일하지 않다면
      다음과 같은 경고메세지가 발생합니다.

      Previous options and warnings not restored.

      이 경고메세지를 off시키기 위하여 지시어 #pragma nopushoptwarn를 사용할
      수 있습니다.

//--------------------------------------------------------------------------

14. #pragma pack

    변수 정렬을 인위적으로 변경시킨다.(보통은 4바이트로 지정되어 있다.)
    . 사용법
      #pragma pack(n)

         위에서, n의 값으로, 1,2,4,8등이 올수 있으며, 특히 네트웍통신쪽을 개발할때
         구조체의 멤버들 align할때 사용하는 것으로서, 빈번하게 사용됩니다.
         구조체 정렬부분은 중요하지만, 여기서는 그쪽까지 언급하기에는 양이 많아서
         여기까지만 설명함.
      #pragma pack(push, n)

      #pragma pack(pop)
    . #pragma pack 지시어는 콤파일러 옵션 -a와 함께 #pragma option을 사용하는
      것과 동일합니다. n은 콤파일러가 저장된 메모리에 데이터를 정렬하는 방법을
      결정하는 byte의 정렬이다. 보다 자세한 사항은 -a 콤파일러 옵션에 관한
      내용을 참고하십시요. #pragma pack은 또한 #pragma option지시어에 push나
      pop을 사용하는것과 동일한 기능을 제공 하도록 push나 pop 아규먼트와 함께
      사용할 수 있습니다.  아래의 내용은 #pragma pack과 #pragma option을 비교한
      내용입니다.
      ━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━
      #pragma pack              ┃     #pragma option
      ━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━
      #pragma pack(n)           ┃     #pragma option -an
      #pragma pack(push, n)     ┃     #pragma option push -an
      #pragma pack(pop)         ┃     #pragma option pop
      ━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━

    예) #pragma pack(push, before_pack, 1)
        구조체 정렬을 1 바이트로 만든다. 1 바이트로 맞추기 전의 정렬 기준을 before_pack에 저장한다

         #pragma pack(pop, before_pack)
        위와 같이 한쌍으로 사용된다. before_pack에 저장된 정렬 기준으로 복원한다.

        다음과 같이 사용할 수도 있다.
         #pragma pack(push, 1)
         #pragma pack(pop)

        다음과 같이 복원없이 지정할 수도 있다.
         #pragma pack(1)

    예) #pragma pack(pop) 이라...아마 이거랑 쌍이 되는게 있을텐데요
         #pragma pack(push,1) 이라던지요.
         이건 구조체를 1바이트로 바이트 정렬하는 겁니다. 디폴트로는 8바이트로 되어 있을겁니다.
         뭐 구조체 크기가 실제로 계산한 것과 맞지 않는 경우가 있는데..이 바이트 정렬 떄문입니다.
         따라서..반드시 맞아야 할 경우는... 위의 코드를 구조체 아래위로 써야 합니다.
//--------------------------------------------------------------------------

15.#pragma package
    . 사용법
      #pragma package(smart_init)
      #pragma package(smart_init, weak)
    . smart_init 아규먼트
      #pragma package(smart_init)는 패키지된 유닛들이 의존할 순서를 결정하기위해
      초기화 되어집니다.(패키지 소스파일 내에 기본적으로 포함됩니다.)
      일반적으로, 패키지들을 생성하는 .CPP 파일들에 #pragma package를 사용할 수
      있습니다.
      이 프라크마는 유닛을 콤파일하는기위한 초기의 순서에 영향을 미칩니다.
      초기화는 다음의 순서에 의하여 발생합니다.
      1. 만일 unitA가 unitB에 의존한다면 unitB는 반드시 unitA전에 초기화
         되어져야만하는 사용("uses")에 의존합니다.
      2. 링크의 순서(The link order)
      3. unit에서의 우선권의 순서.(Priority order within the unit.)

      보통의 .OBJ 파일들은(unit들로 생성하지 않은), 첫째로 우선권의 순서에 따라
      초기화가 일어나고서 링크가 됩니다. .OBJ 파일들의 링크 순서의 변경은
      글로발 오브젝트가 호출되어져 생성되는 순서에 의해 변경됩니다.

      다음의 예는 보통의 .OBJ 파일들과 unit들의 초기화에 어떤 차이점이 있는가를
      보여줍니다. 세개의 unit 파일들 A,B,C가 #pragma package(smart_init)를
      사용하여 "smart initialized"되고 우선권은 10, 20, 30의 값을 갖는다고
      예를 듭니다. 함수는 우선권의 값과 parent .OBJ에 의하여 이름지어져 a10,
      a20, a30, b10등과 같은 이름을 갖습니다. 세가지는 모두 unit들이며 A는 B와
      C를 사용하며 A,B,C의 순서로 링크되고 초기화의 순서는 다음과 같습니다.
           B10 B20 B30 C10 C20 C30 A10 A20 A30
      위와 같이 되었다면 .OBJ 파일들은 (unit들이 아니다)다음의 순서가 되어질
      것입니다.
           A10 B10 C10 A20 B20 C20 A30 B30 C30
      #pragma package(smart_init)를 사용한 .CPP 파일들은 또한 #pragma package
      (smart_init)를 정의한 .CPP 파일로부터 다른 .OBJ 파일들을 참조하는 #pragma
      link를 필요로 하며 unit에 의해 결정되어져야만 합니다. #pragma link는, 결정
      되지 않은 .OBJ는 라이브러리 등에 의하여 여전히 결정되어질 수 있도록 참조
      할 수 있습니다.
    . weak packages
      #pragma package(smart_init, weak)지시어는 .OBJ 파일이 패키지의 .BPI와
      .BPL 파일들에 정장되는 방법에 영향을 미칩니다. 만일 #pragma package(smart_
      init, weak)가 unit파일 내에 나타난다면 콤파일러는 가능하다면 BPL들로부터
      unit을 생략하고, 다른 에플리케이션이나 패키지에 의해 필요로 할 때면
      비 패키지화된(non-packaged) 로칼 복사본의 unit을 생성합니다. 유닛이 이
      지시어와 함께 콤파일 되었다는 것은 약하게 패키지화 되었음을 이야기 합니다.
      ("weakly packaged")
      #pragma package(smart_init, weak)는 동일한 외부 라이브러리(external librar
      y)들에 의존할수 있는 여러 패키지들 사이에서의 충돌을 제거하는데 사용되어
      집니다.  #pragma package(smart_init, weak) 지시어를 가지는 unit 파일들은
      글로발 변수들을 갖지 않아야 합니다.

//--------------------------------------------------------------------------
16.#pragma resource
    . 사용법
      #pragma resource "*.dfm"
    . 이 프라그마는 form unit에 의해 선정되어지는 파일로서 일치되는 .DFM 파일과
      헤더파일을 필요로 합니다. 이러한 모든 파일들은 IDE에 의해 관리되어집니다.
      만일 폼을 위한 다른 변수들을 필요로한다면 pragma resource가 사용되어지고난
      후에 즉시 선언되어져야만 합니다. 선언은 반드시 form이 되어져야만 합니다.
          TFormName *Formname;

//--------------------------------------------------------------------------
17.#pragma startup
    . 사용법
      #pragma startup function-name <priority>
      #pragma exit function-name <priority>
    . #pragma exit의 내용을 참조하십시요.

//--------------------------------------------------------------------------
18.#pragma warn
    . 사용법
      #pragma warn [+:-:.]www
    . warn지시어를 이용하면 특정 명령라인 옵션 -wxxx를 우선할 수 있습니다.
      #pragma warn -aus 스위치를 사용하면 함수 단위로 취급됩니다. 개별적인
      변수들을 위해서 함수 내부에서 경고를 off시킬수는 없습니다. 함수 전체를
      off시키거나 혹은 그렇지 않거나 둘중 하나입니다.
    ex)
    #pragma warn +xxx
    #pragma warn -yyy
    #pragma warn .zzz

    위의 예에서는 xxx경고문은 on되고 yyy경고문은 off되며 zzz경고문은 파일의
    컴파일이 시작할 때 갖고 있던 값으로 재저장됩니다.

//----- End of Document ---------------------------------------------------- 
19. #pragma once

 1. 한번 컴파일 되면 더 이상 컴파일 하지 않는다는 뜻입니다.
 여러개의 cpp파일이 있을때, 하나의 cpp화일이 수정되면, 그 화일만 컴파일하고
 나머지는 하지말아란 뜻이죠.   ( 여러 번 인클루드 되는 것을 컴파일러 차원에서 막아줌 )

 2. #ifndef ~ #endif 와 같은 역할을 한다.

 3. 매크로들의 중복 정의를 막고, 전역변수에 static 키워드를 써줄 필요가 없어짐.

 4. VC++ 에서는 되고, 다른 컴파일러는 안될 수도 있음.

 5. 분할 컴파일시

 

이것을 사용하면 빌드시 컴파일러에 의해 해당 파일을 단 한번만 열게 된다... 그러므로 컴파일 타임을 줄일 수 있고 모듈에서 가장 먼저 나온 #include문에서 해당 파일을 열게 되므로 재정의에 의한 오류를 방지할 수 있다...

 

예제)

// exam.h file

#ifndef __EXAM__

#define __EXAM__

...

#endif

->

// exam.h file

#pragma once

...

 

//--------------------------------------------------------------------------

20. #pragma data_seg

   dll에서 데이터 공유하고자 할 때 쓰임

  예) 실행파일에는 코드영역과 데이터영역이 구분되어 있다는 것은 아시지요.
┌───────┐
│                     │
│                     │
│   데이터영역   │
│                     │
│                     │
├───────┤
│                     │
│                     │
│     코드 영역   │
│                     │
│                     │
└───────┘
   이런 식의 그림은 아마 어디선가 많이 보셨을겁니다.(그림이 깨지네요.편집할 땐 제대로 보였는데...)
   이런 영역을 section이라고 하지요. 위의 설명에 나오는 section이라는 용어가 이것입니다.
   실제로 데이터 영역과 코드 영역외에도 exe나 dll에는 여러 section을 포함할 수 있습니다.
   이건 dumpbin이라는 툴로 살펴볼 수 있습니다.
   제 컴(Windows XP)에서 dumpbin c:\windows\notepadd.exe 를 해 보았더니

   2000 .data
   2000 .rsrc
   7000 .text

   이렇게 나오는 군요.

   여기서 .data에는 초기화된 데이터가 .rsrc에는 리소스들이, .text에 코드가 들어갑니다.
   이러한 .data, .rsrc, .text 등은 일반적으로 정해져 있는 것들입니다.
   위 MSDN의 설명에 있는 section-name이라는 것이 바로 .data, .rsrc, .text 등을 뜻하는 겁니다.
   즉, #pragma code_seg( .data ) 처럼 사용한다는 거지요.
   그리고 Specifies a code section where functions are to be allocated.라는 설명은 Specifies a section where functions or data or etc. are to be allocated. 이렇게 이해하면 더 나을 듯 하네요.

   그런데 이런 정해진 이름말고도 사용자가 새로운 영역을 정할 수 있습니다.

   #pragma data_seg("Shared")
   DWORD g_dwThreadIdPMRestore = 0;
   HWND g_hwnd = NULL;
   #pragma data_seg()

   이런 식으로 하면 g_dwThreadIdPMRestored와 g_hwnd가 디폴트 데이터 섹션인 .data에 배치되지 않고, Shared라는 이름으로 만들어진 섹션에 배치되는 것입니다.

 

//--------------------------------------------------------------------------

21. #pragma warning

    컴파일시에 어떤 조건(#if, #ifndef)에의해 개발자에게 어떤것을 알려주고 싶을 경우 사용.

    예) #pragma warning(disable:xxxx)
         지정된 xxxx번대의 경고 메세지를 디스플레이하는 것을 막는다. (xxxx는 번호)

          warning( disable : 4705 )

          : 특정 warnning 을 체크하지 않음, 이럴 경우 4705번 warnning은 나타나지 않는다

         #pragma warning(default:xxxx)
         지정된 xxxx번의 경고 메세지의 설정을 원래의 프로젝트 설정으로 복원한다

 

//--------------------------------------------------------------------------

22. #pragma code_seg

   MSDN에 있는 내용
   #pragma code_seg( ["section-name"[,"section-class"] ] )

   Specifies a code section where functions are to be allocated. The code_seg pragma specifies the default section for functions. You can, optionally, specify the class as well as the section name. Using #pragma code_seg without a section-name string resets allocation to whatever it was when compilation began.

 

//--------------------------------------------------------------------------

23. #pragma deprecated

    C#의 Obsolete attribute와 비슷한 의미입니다.
    즉, 경고가 발생한 클래스 혹은 메서드 등이 이후에는 지원되지 않음을 나타내는 의미입니다.
    그러므로 당장은 문제가 없습니다.

    컴파일러 specific 한..그런 옵션 지시자라고 보시면 됩니다.

 

//--------------------------------------------------------------------------

#pragma는 표준 C/C++ 문법인데 각 compiler 마다 다른 명령을 제공한다... 고로 Linux나 Unix의 cc에서는 작동하지 않을 수도 있다는 것! (Visual C++에선 언제나 call...)

 

  1. pragma 는 #로 시작하는 전처리구문 지시자 중 컴파일러에 종속적인 명령으로, 컴파일러에 특정한 옵션 명령을 내리기 위해 사용한다.

이것은 컴파일러에 종속적이기 때문에 컴파일러를 변경했을 경우 실행을 보장하지 못한다.

 

pragma 의 의미를 action 으로 많이들 알고 계시는데, 인터넷에서 제가 알아본바로는, 사전적인 의미는 "만능" 입니다.  어원설명 원문은, 아래를 참고하세요.

 

A pragma (from the Greek word meaning action) is used to
direct the actions of the compiler in particular ways, but
has no effect on the semantics of a program (in general).

Pragmas are used to control listing, to define an object
configuration (for example, the size of memory), to control
features of the code generated (for example, the degree of
optimization or the level of diagnostics), and so on.

Such directives are not likely to be related to the rest of
the language in an obvious way. Hence the form taken should
not intrude upon the language, but it should be uniform.

Thus, the general form of pragmas is defined by the language.
They start with the reserved word pragma followed by a pragma
identifier, optionally followed by a list of arguments enclosed
by parentheses, and terminated by a semicolon.

The overall syntax of the pragma identifier and arguments is
similar to that of a procedure call. Pragmas are allowed at
places where a declaration or a statement is allowed; also at
places where other constructs that play the role of declarations
(for example clauses) are allowed.

 

pragma 는 컴파일에게 그 뒤에오는 내용에 따라 어떤일을 하라는 전처리명령입니다.

 

C++는 컴파일하고 나면 함수의 이름이 바뀌게 되는데 이것을 name mangling이라고 합니다.

그래서 만일 dll로 작성한 함수를 불러 사용하게 되면 같은 이름을 찾을 수 없다는 오류가 나게 됩니다.

만일 dll에서 printString라는 함수를 만들었다고 가정을 합니다. 그러면 컴파일하고 난 후의 함수의 이름은 printString@@YAXXZ와 같은 형태로 만들어 집니다.
그런데 이 함수를 불러 사용하는 곳은 printString이라는 것만 알지 위의 것과 같은 알지 못합니다. 그래서 #pragma라는 키워드를 사용해서 name mangling을 방지하게 되는 것입니다.
이 mangling된 이름을 찾기 위해서는 VC++ Tool에 보면 depends를 실행하고 만들dll을 drag&drop하면 이것을 찾을 수 있습니다.

  1. pragma comment(linker, "/export:printString=?printString@@YAXXZ")와 같이사용하면됩니다.

즉 #pragma는 원래의 함수 이름을 c++의 암호명에 대한 별칭으로 추가하도록 지시하며 링커에게 /export옵션을 전달해 주는것입니다.
그리고 dll에서는 원래의 함수를 export(수출??말이 좀 이상하지만 대부분 이렇게 많이 쓰니까..^^)해야 하고 이 함수를 호출하는 쪽에서는 import(수입) 옵션을 써 주어야만 함수를 제대로 호출할 수 있습니다.

 

pragma 앞에 #이 있는 걸 보면 아시겠지만 pragma는 precompiler입니다.

compile할 때 platform이 틀려지거나 cpu가 틀려지거나 할 때 compile option을 주게 됩니다.

vc++을 써보셨으면 아실텐데, project settings( ALT+F7 )에서 c/c++ tab에 보면 project options이 있습니다. link tab에도 project options가 있죠.

pragma가 바로 그런 역할을 하는 precompiler입니다.

vc++이야 ide니까 project settings라는 편한 환경을 지원하지만 만약 code호환성을 생각한다면 pragma를 쓰는 게 좋죠.

 

< api나 mfc의 구분과 관계없이 해당 컴파일러에서 사용하는 명령 >

#pragma warn- // warning 디스어블

  1. pragma warn+ // warning 인에이블
  2. pragma opt- // 최적화 안 함
  3. pragma opt+ // 최적화 함
  4. pragma savereg- // 레지스터 저장 안 함
  5. pragma savereg+ // 레지스터 저장 함
  6. pragma library mylib.lib // 링크 라이브러리 지정

 
※  MSDN  /  "Programming Applications for Microsoft Windows"(Jeffrey Richer 저) 참조


Posted by 세모아
,

아래의 TRACE(.) 안될때는, OutputDebugString(.) 사용


#include <windows.h>


 char buf[256];

 sprintf(buf,"%d \n",nFingerCount);

 OutputDebugString(buf);




TRACE(.) 위한 define문 :

#define ENABLE_TRACE  // Can depend on _DEBUG or NDEBUG macros

---------------------------------

출처: http://blog.daum.net/pg365/45


DebugView는 프로그램이 실행되면서 출력하는 디버그 메시지를 표시하는 디버깅 도구입니다. Visual Studio에서 프로그램을 디버깅으로 실행(F5 키를 눌러 실행)할 때, TRACE가 내보내는 메시지는 통합환경 하단의 Output 창에 출력 됩니다. 하지만, 디버그로 컴파일 된 실행 파일을 Visual Studio가 없는 환경에서 실행할 때 출력되는 디버그 메시지들은 어떻게 볼 수 있을까요? 이런 경우 사용 가능한 도구가 DebugView 입니다.

 

아래와 같이, 코드내에 TRACE를 써서 두 변수 x, y 값을 디버그 메시지로 출력해 보겠습니다.

 

int x = 5;
double y = 5.5;

 

TRACE ("x = %d, y=%f\n", x, y);

 

Visual Studio 상에서 F5 키를 눌러 디버깅으로 실행하면 하단 Output 창에 x, y 변수의 값이 찍히는 것이 보입니다. 디버깅을 위해 주로 사용하던 익숙한 방법입니다.

 

 

 

이번에는, 코드는 디버그로 컴파일 되어 있지만, Ctrl+F5 키를 눌러 디버깅 없이 실행해 보겠습니다. 즉, Visual Studio가 코드 디버깅에 개입하지 않고 실행 파일만 따로 실행함을 의미합니다. 물론, DebugView는 먼저 실행되고 있어야 합니다.

 

그렇다면, 다음 그림과 같이 DebugView 창에서 TRACE로 내보낸 디버그 메시지가 표시됩니다.

 

 

실제로 DebugView를 실행해 보면, 정작 현재 디버깅 중인 프로그램의 디버깅 메시지만 출력되는 것이 아니라 다른 프로그램들이 내보내는 디버깅 메시지들도 뒤섞여 출력되는 것을 볼 수 있습니다. 이럴 때는 필터 옵션을 잘 사용하는 것이 좋겠습니다.

 

DebugView에 대한 소개 글을 읽어 보면, 로컬 PC의 디버깅 뿐만이 아니라 네트워크 상에 있는 다른 컴퓨터도 디버깅 가능하고. 커널-모드 디버깅과  WIN32 디버그 출력도 표시할 수 있다고 합니다.


아래 페이지에서 DebugView 프로그램을 무료로 다운받아 사용하실 수 있습니다.

http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx

Posted by 세모아
,

Visual C++의 .NET 프로그래밍

How to: Parse Strings Using the Split Method (C++/CLI)


Example


// regex_split.cpp

// compile with: /clr

using namespace System;


int main(array<System::String ^> ^args)

//가능함. int main()

{

   String^ delimStr = " ,.:\t";

   Console::WriteLine( "delimiter : '{0}'", delimStr );

   array<Char>^ delimiter = delimStr->ToCharArray( );

   array<String^>^ words;

   String^ line = "one\ttwo three:four,five six seven";


   Console::WriteLine( "text : '{0}'", line );

   words = line->Split( delimiter );

   Console::WriteLine( "Number of Words : {0}", words->Length );

   for (int word=0; word<words->Length; word++)

      Console::WriteLine( "{0}", words[word] );


   return 0;

}

결과

delimiter : ' ,.:       '

text : 'one     two three:four,five six seven'

Number of Words : 7

one

two

three

four

five

six

seven



Posted by 세모아
,
C++/CLI Console 프로그램 코드에서
 MessageBox 사용시 다음 에러 발생하면 해결책은?
 - 에러 : /LNK2028: unresolved token(0A00003D) "extern "C" int __stdcall MessageBoxW .....
 - 해결책 : Edit your project properties, find the Linker Inputs option,
             and add kernel32.lib user32.lib advapi32.lib which are the usual libraries needed by Win32 code.


Posted by 세모아
,

VC++6에는 F4/Shift+F4로 찾기 결과창에서 앞뒤로 이동하였는데,

VS2013에서는 F8로 되고,

F4는 Properties 창이 띄우기에 불편하여

손에 익숙하고 이동이 빠른 F4 로 변경하는 방법:


아래 그림의 것을 서로 바꾸어 설정한다.


F4 / Shift+F4


F8/Shift+F8




Posted by 세모아
,

COPYDATASTRUCT 의

cbData에 숫자를, lpData에 문자열만 넣어서 

간단한 자료만 송수신 하는 예제 코드




송신부 (C#)

        public struct COPYDATASTRUCT

        {

            public IntPtr dwData;

            public int cbData;

            [MarshalAs(UnmanagedType.LPStr)]

            public string lpData;

        }


        private void OnButtonSendClick(object sender, EventArgs e)

        {

            string msg = this.tbMsg.Text.Trim();


            if (string.IsNullOrEmpty(msg))

            {

                MessageBox.Show("메세지를 입력해주세요");

                return;

            }


            IntPtr hwndRcvr = FindWindow(null, "CppReceiveWM_COPYDATA"); //"LHJ WINDOW");

//                byte[] buff = System.Text.Encoding.Default.GetBytes(msg);


                COPYDATASTRUCT cds = new COPYDATASTRUCT();

                cds.dwData = IntPtr.Zero;

//                cds.cbData = buff.Length + 1; //+1을 빼면 수신측에서 cds.lpdata의 뒤에 이상한 글자 붙음.

                cds.cbData = msg.Length+1; //+1을 빼면 수신측에서 cds.lpdata의 뒤에 이상한 글자 붙음.

                cds.lpData = msg;


                SendMessage(hwndRcvr, WM_COPYDATA, 0, ref cds);

        }





수신부 (C++)

 : memcpy_s(.) 을 없애서 빠른 응답속도를 지원토록 함


typedef struct tagCOPYDATASTRUCT2 {
    ULONG_PTR dwData;
    DWORD cbData;
     PVOID lpData;
} COPYDATASTRUCT2, *PCOPYDATASTRUCT2;


INT_PTR CALLBACK DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

//LHJ version //15.3.28 ---------------

    switch (message)

    {

case WM_COPYDATA:        

HandleWMCOPYDATA(hWnd, wParam, lParam);

break;

    default:

return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

}


bool HandleWMCOPYDATA(HWND hWnd, WPARAM wParam, LPARAM lParam)

{

PCOPYDATASTRUCT2 pcds;

pcds = (PCOPYDATASTRUCT2)lParam;

try 

{

    // If the size matches

int nsize = pcds->cbData;

{

        SetDlgItemInt(hWnd, IDC_NUMBER_STATIC, nsize, TRUE);

//   std::wstring s1 = (LPCWSTR)pcds->lpData; //송신부가  [MarshalAs(UnmanagedType.LPStr)] 이므로 LPCWSTR은 에러


std::string s2 = (LPSTR)pcds->lpData;

std::wstring s1;

s1.assign(s2.begin(), s2.end());  


// SetDlgItemTextW(hWnd, IDC_MESSAGE_STATIC, (LPCWSTR)pcds->lpData); // >image);

SetDlgItemText(hWnd, IDC_MESSAGE_STATIC, s1.c_str()); // >image);




// The receiving application should consider the data (pcds->lpData) 

        // read-only. The pcds parameter is valid only during the processing 

        // of the message. The receiving application should not free the 

        // memory referenced by pcds. If the receiving application must 

        // access the data after SendMessage returns, it must copy the data 

        // into a local buffer. 

//        memcpy_s(&myStruct, sizeof(myStruct), pcds->lpData, pcds->cbData);

//        memcpy_s(&myStruct, nsize, pcds->lpData, pcds->cbData);


        // Display the MY_STRUCT value in the window.

        // Display the MY_STRUCT value in the window.

//        SetDlgItemInt(hWnd, IDC_NUMBER_STATIC, myStruct.Number, TRUE);

//        SetDlgItemText(hWnd, IDC_MESSAGE_STATIC, myStruct.Message);


//wchar_t text1[50000];

//mbstowcs(text1, myStruct.Message, strlen(myStruct.Message) + 1);

//        SetDlgItemText(hWnd, IDC_MESSAGE_STATIC, text1);


//        SetDlgItemInt(hWnd, IDC_NUMBER_STATIC, pMyStruct->Number, TRUE);

// LPCTSTR s2;

// s2 = (LPCTSTR) pMyStruct->Message;

//        SetDlgItemText(hWnd, IDC_MESSAGE_STATIC, s2);

    }

}

catch( int)

{

//MessageBox(hWnd, L"1", L"2", MB_OK);

}

return true;

}



Posted by 세모아
,


출처 : http://myblue0324.tistory.com/118


  1. // 방법1.  
  2. std::string str = "string";  
  3. std::wstring wstr = L"";  
  4.   
  5. wstr.assign(str.begin(), str.end());  
  6.   
  7. // 방법2.   
  8. USES_CONVERSION;  
  9.   
  10. std::string str = "string";  
  11. std::wstring wstr(A2W(str.c_str()));  


2. std::wstring을 std::string으로 변환.

  1. // 방법1.  
  2. std::wstring wstr = L"string";  
  3. std::string str = "";  
  4.   
  5. str.assign(wstr.begin(), wstr.end());  
  6.   
  7. // 방법2.  
  8. USES_UTF8_CONVERSION;  
  9.   
  10. std::wstring wstr = L"string";  
  11. str::string str(W2A(wstr.c_str()));  


위의 문자열을 CString형으로 변환하고자 할 경우에는 간단하게 아래와 같이 변경이 가능합니다.

  1. #ifdef _UNICODE  
  2.     std::wstring s = L"string";  
  3.     CString str(s.c_str());   
  4. #else  
  5.     std::string s = "string";  
  6.     CString str(s.c_str());   
  7. #endif  


Posted by 세모아
,

My 정리 :


std::string s2 = (LPSTR)pcds->lpData;


To "convert" a std::string to a LPCSTR depends on the exact context but usually calling .c_str() is sufficient.

This works.

void TakesString(LPCSTR param);

void f(const std::string& param)
{
    TakesString(param.c_str());
}

Note that you shouldn't attempt to do something like this.

LPCSTR GetString()
{
    std::string tmp("temporary");
    return tmp.c_str();
}

The buffer returned by .c_str() is owned by the std::string instance and will only be valid until the string is next modified or destroyed.



정의 -----------------------

LPSTR - (long) pointer to string - char *

LPCSTR - (long) pointer to constant string - const char *

LPWSTR - (long) pointer to Unicode (wide) string - wchar_t *

LPCWSTR - (long) pointer to constant Unicode (wide) string - const wchar_t *

LPTSTR - (long) pointer to TCHAR (Unicode if UNICODE is defined, ANSI if not) string - TCHAR *

LPCTSTR - (long) pointer to constant TCHAR string - const TCHAR *



std:string 정의 페이지

http://www.cplusplus.com/reference/string/string/



원본 페이지 :



from: http://stackoverflow.com/questions/1200188/how-to-convert-stdstring-to-lpcstr


How can I convert a std::string to LPCSTR? Also, how can I convert a std::string to LPWSTR?

I am totally confused with these LPCSTR LPSTR LPWSTR LPCWSTR?

Are LPWSTR and LPCWSTR are the same?

shareimprove this question

str.c_str() gives you a const char *, which is an LPCSTR (Long Pointer to Constant STRing) -- means that it's a pointer to a 0 terminated string of characters. W means wide string (composed of wchar_t instead of char).

shareimprove this answer
4 
Minor picky point: on x64 LPCSTR would be a 64-bit pointer to a (constant) null-terminated string. –  Joel Jul 30 '09 at 14:41
1 
the C in LPCSTR stand for const not C –  mathk Jan 30 '13 at 9:14

Call c_str() to get a const char * (LPCSTR) from a std::string.

It's all in the name:

LPSTR - (long) pointer to string - char *

LPCSTR - (long) pointer to constant string - const char *

LPWSTR - (long) pointer to Unicode (wide) string - wchar_t *

LPCWSTR - (long) pointer to constant Unicode (wide) string - const wchar_t *

LPTSTR - (long) pointer to TCHAR (Unicode if UNICODE is defined, ANSI if not) string - TCHAR *

LPCTSTR - (long) pointer to constant TCHAR string - const TCHAR *

You can ignore the L (long) part of the names -- it's a holdover from 16-bit Windows.

shareimprove this answer
3 
+1 Make it very easy. –  Sauron Jul 29 '09 at 13:24
   
Thank u very Much for ur support –  Cute Jul 29 '09 at 13:39

These are Microsoft defined typedefs which correspond to:

LPCSTR: pointer to null terminated const string of char

LPSTR: pointer to null terminated char string of char (often a buffer is passed and used as an 'output' param)

LPCWSTR: pointer to null terminated string of const wchar_t

LPWSTR: pointer to null terminated string of wchar_t (often a buffer is passed and used as an 'output' param)

To "convert" a std::string to a LPCSTR depends on the exact context but usually calling .c_str() is sufficient.

This works.

void TakesString(LPCSTR param);

void f(const std::string& param)
{
    TakesString(param.c_str());
}

Note that you shouldn't attempt to do something like this.

LPCSTR GetString()
{
    std::string tmp("temporary");
    return tmp.c_str();
}

The buffer returned by .c_str() is owned by the std::string instance and will only be valid until the string is next modified or destroyed.

To convert a std::string to a LPWSTR is more complicated. Wanting an LPWSTR implies that you need a modifiable buffer and you also need to be sure that you understand what character encodingthe std::string is using. If the std::string contains a string using the system default encoding (assuming windows, here), then you can find the length of the required wide character buffer and perform the transcoding using MultiByteToWideChar (a Win32 API function).

e.g.

void f(const std:string& instr)
{
    // Assumes std::string is encoded in the current Windows ANSI codepage
    int bufferlen = ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), NULL, 0);

    if (bufferlen == 0)
    {
        // Something went wrong. Perhaps, check GetLastError() and log.
        return;
    }

    // Allocate new LPWSTR - must deallocate it later
    LPWSTR widestr = new WCHAR[bufferlen + 1];

    ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), widestr, bufferlen);

    // Ensure wide string is null terminated
    widestr[bufferlen] = 0;

    // Do something with widestr

    delete[] widestr;
}
shareimprove this answer
   
How to Convert std::String to LPWSTR ??? –  Cute Jul 29 '09 at 13:44
   
Scholar and a gentleman! –  Russbear Aug 2 '11 at 22:02

Using LPWSTR you could change contents of string where it points to. Using LPCWSTR you couldn't change contents of string where it points to.

std::string s = SOME_STRING;
// get temporary LPSTR (not really safe)
LPSTR pst = &s[0];
// get temporary LPCSTR (pretty safe)
LPCSTR pcstr = s.c_str();
// convert to std::wstring
std::wstring ws; 
ws.assign( s.begin(), s.end() );
// get temporary LPWSTR (not really safe)
LPWSTR pwst = &ws[0];
// get temporary LPCWSTR (pretty safe)
LPCWSTR pcwstr = ws.c_str();

LPWSTR is just a pointer to original string. You shouldn't return it from function using the sample above. To get not temporary LPWSTR you should made a copy of original string on the heap. Check the sample below:

LPWSTR ConvertToLPWSTR( const std::string& s )
{
  LPWSTR ws = new wchar_t[s.size()+1]; // +1 for zero at the end
  copy( s.begin(), s.end(), ws );
  ws[s.size()] = 0; // zero at the end
  return ws;
}

void f()
{
  std::string s = SOME_STRING;
  LPWSTR ws = ConvertToLPWSTR( s );

  // some actions

  delete[] ws; // caller responsible for deletion
}
shareimprove this answer

The MultiByteToWideChar answer that Charles Bailey gave is the correct one. Because LPCWSTR is just a typedef for const WCHAR*widestr in the example code there can be used wherever a LPWSTR is expected or where a LPCWSTR is expected.

One minor tweak would be to use std::vector<WCHAR> instead of a manually managed array:

// using vector, buffer is deallocated when function ends
std::vector<WCHAR> widestr(bufferlen + 1);

::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), &widestr[0], bufferlen);

// Ensure wide string is null terminated
widestr[bufferlen] = 0;

// no need to delete; handled by vector

Also, if you need to work with wide strings to start with, you can use std::wstring instead of std::string. If you want to work with the Windows TCHAR type, you can use std::basic_string<TCHAR>. Converting from std::wstring to LPCWSTR or from std::basic_string<TCHAR> to LPCTSTR is just a matter of calling c_str. It's when you're changing between ANSI and UTF-16 characters that MultiByteToWideChar (and its inverse WideCharToMultiByte) comes into the picture.

shareimprove this answer

The conversion is simple:

std::string str; LPCSTR lpcstr = str.c_str();

shareimprove this answer

Converting is simple:

std::string myString;

LPCSTR lpMyString = myString.c_str();

One thing to be careful of here is that c_str does not return a copy of myString, but just a pointer to the character string that std::string wraps. If you want/need a copy you'll need to make one yourself using strcpy.

shareimprove this answer
   
How to Convert std::String to LPWSTR ??? –  Cute Jul 29 '09 at 13:44

The easiest way to convert a std::string to a LPWSTR is in my opinion:

  1. Convert the std::string to a std::vector<wchar_t>
  2. Take the address of the first wchar_t in the vector.

std::vector<wchar_t> has a templated ctor which will take two iterators, such as the std::string.begin() and .end() iterators. This will convert each char to a wchar_t, though. That's only valid if the std::string contains ASCII or Latin-1, due to the way Unicode values resemble Latin-1 values. If it contains CP1252 or characters from any other encoding, it's more complicated. You'll then need to convert the characters.


Posted by 세모아
,