import javax.swing.*;
import java.awt.*;

public class TabbedPaneFrame extends JFrame{
	public TabbedPaneFrame(){
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		createTabbedPane();
		setSize(300,300);
		setVisible(true);
	}
	
	void createTabbedPane(){
		JTabbedPane tPane = new JTabbedPane();
		add(tPane);
		tPane.addTab("박지연", new JLabel(new ImageIcon("images/back.jpg")));
		tPane.addTab("함은정", new JLabel(new ImageIcon("images/kwak.jpg")));
		//tPane.addTab("티아라", new JPanel(new SnakeFrame.GroundPanel()));
	}
	
	public static void main(String args[]){
		new TabbedPaneFrame();
	}
}
블로그 이미지

맨오브파워

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

,
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JApplet;
import javax.swing.JPanel;

public class MyApplet extends JApplet {
 MyPanel p = new MyPanel();

 public MyApplet() {
  setContentPane(p);
 }

 public void init() {
	 // String value = getParameter("font");
	 // p.setFSize(Integer.parseInt(value));	 
	 p.repaint();
 }

 public void start() {
 }

 public void stop() {
 }
}

class MyPanel extends JPanel {
 int fSize = 40;

 public MyPanel() {
  setBackground(Color.YELLOW);
 }

 void setFSize(int s) {
  fSize = s;
 }

 public void paintComponent(Graphics g) 
 {
	  super.paintComponent(g);
	  g.setColor(Color.RED);
	  g.setFont(new Font("Ravie", Font.ITALIC, 40));
	  g.drawString("Hello", 100, 100);
 }
}
블로그 이미지

맨오브파워

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

,

Java에서 대량의 자료를 추가/삭제하며 처리하기 위해서는 무엇을 사용해야 할까요?

연구실에서 Java를 한번쯤 공부해 본 사람이라면 보통 “Vector Class”라고 대답을 할 것입니다. 정답이죠. Vector Class는 대량의 자료를 가질수 있으며, 추가/삭제또한 자유롭게 처리가 가능합니다. 그럼 뭐가 문제라서 이런 글을 쓰는것일까요?

단순히 “처리되는가” 를 넘어서 “빠르게 처리할수 있는가” 를 생각해 본다면,
위에서의 대답 “Vector Class” 는 X에 가까운 답이라고 할 수 있기 때문입니다.

우선, Java에서 제공하는 “대용량 자료처리 개념” 은 여러가지 상위 인터페이스를 통해서 구현할 수 있습니다. (Collection, Iterator, Enumeration, Map등등) 각각 독특한 특징을 가지고 있습니다만, 이번에 다룰 내용은 Collection이하의 객체들이 되겠습니다.(나머지에 대해서도 다음 기회에 이야기 하도록 하겠습니다.)

Collection Interface는 “내부에 포함되는 요소는 순서를 가진다” 라는 특징을 가지고 있습니다. (이와 반대로 포함요소가 순서에 관계없이 저장되는녀석이 Map계열입니다.)
Collection을 계승(상속)해서 실제 구현된 객체들도 여럿 있습니다만, 그중에서도 대표적인 ArrayList, LinkedList, Vector 의 특징을 간단하게 설명하면 다음과 같습니다.
(HashSet, TreeSet같은 특이한 녀석들도 있습니다만… 일반적인 경우에 사용되는 녀석들은 아닌관계로, 설명은 다음기회로 넘기겠습니다…)

사용자 삽입 이미지

1. Vector

Java 1.0때 만들어져, 지금까지 유지되어온 클래스.
1.0버젼에서는 지금과 같은 List관련 객체들은 없었습니다.
이 버젼대에서 애용되었던 것이 Vector입니다.

Vector의 기본적인 동작은 다음에 설명할 ArrayList와 동일하기 때문에 넘어가기로 하고, 다른점만 설명하겠습니다.
Vector와 이후에 등장하는 List객체의 다른점은 “동기화(synchronize)”처리에 있습니다.
우선 “동기화” 라고 하는 개념에 대해서 간단하게 짚고 넘어가도록 하겠습니다.

두명의 학생이 하나의 컴퓨터를 사용하려고 합니다. 사용순서에 제한이 없기 때문에 서로 먼저 사용하려고 싸우게 되죠. 그러다보니 다음과 같은 상황이 발생합니다. 학생A가 워드로 “가나다라마바사…. ”를 적고 있는도중에 학생B가 키보드를 가로채서 “ABCDEFG…”를 입력해 버립니다. 두 학생은 하나의 자원(컴퓨터)를 공유하지만, 사용 순서에 대한 제한이 전혀 없기때문에 서로 상대방의 자료를 덮어써 버리는 일이 발생하게 되죠.
이것을 방지하기 위해서 자바에서는 synchronized 라는 키워드를 만들어 두었습니다. 이 키워드를 사용하면 공통된 자원에 접근하는것은 [반드시 한번에 하나!] 라는 조건이 붙게 되죠. 한 스레드(학생A)이 공유자원(컴퓨터)에 작업을 마치기 전 까지는 다른 스레드(학생B)가 공유자원(컴퓨터)에 접근을 할 수 없도록 약속해 버리는 것입니다. 이런 과정을 “동기화” 라고 합니다.

복수의 스레드로부터 데이터의 추가/삭제처리가 이루어졌을경우에도 내부의 데이터는 “안전”하게 한번에 한 스레드씩 처리가 이루어지도록 되어있다는 것이죠. 데이터의 안정성을 놓고 보았을때, 정말 좋은 일이 아닐수 없습니다.
… 만, 동기화가 문제시 되는 경우는 어디까지나 “공유자원”과 “복수사용자” 가 존재할때 성립되는 것입니다. 한개의 자원을 하나의 스레드가 사용하는 경우에도 동기화를 고려해서 처리를 하게 되면, 오히려 성능의 저하를 가져오게 되는 문제가 발생하죠. Vector의 경우는 “무조건 동기화” 이기 때문에 단일 스레드 처리에서는 앞으로 설명할 ArrayList나 LinkedList보다 성능이 떨어집니다. 자바 1.2 부터의 Vector의 주 사용목적은 1.0버젼과의 호환성이라고 생각하시는게 가장 좋을겁니다. 거의 쓸 일이 없다는 거죠. 혹시 동기화처리가 필요한 경우는 Vector를 이용하기 보다는 Collection. synchronizedCollection(Collection c)나synchronizedList, Map을 이용하는것이 성능상 바람직하겠습니다.

2. ArrayList

Java2 (1.2)에서 새로이 도입된 Collection의 구현객체입니다.

자료의 추가/삭제 등 기본적인 기능은 Vector와 동일하나, 내부적인 자동 동기화 기능이 삭제되어있죠. 때문에 다수의 스레드 환경에서 사용하기 위해서는 Vector설명에서 이야기했었던 Collection. synchronizedCollection(Collection c)를 이용해서 동기화 옵션을 설정해 주면 됩니다.
이름에서 알 수 있듯이, 내부적으로 자료를 Array(배열)구조로 가지고 있는 객체이죠. 데이터의 추가 / 삭제를 위해서 내부적 임시배열을 작성후 데이터를 복사하는 방법을 사용하고 있습니다.

사용자 삽입 이미지

때문에, 대량의 자료를 추가 / 삭제하는 경우에 내부적인 처리량이 늘어나서 상당한 성능저하를 가져옵니다. (C에서 배열에 데이터 추가/삭제 해 보신분은 아시리라 믿습니다.)
대신, 각 데이터의 인덱스를 가지고 있기 때문에, 필요한 데이터에의 접근이 한번만에 가능하죠. (C에서 포인터를 이용해서 한방에 원하는 데이터에 접근하는것과 같습니다.)
보통, 많은 데이터를 한번에 몽땅 가져와서 여러번 참조해 쓸 때 최상의 성능을 나타내는 객체가 되겠습니다.
간단한 예로 정리를 하면,
물건을 사기위해서 5명의 사람이(손님 A,B,C,D,E) 의자에 앉아 차례를 기다리고 있는데,미리 순서를 예약해 둔 F라는 사람이 C의 앞에 불쑥 들어서서 자리를 비켜달라고 합니다. 예약을 했기때문에 C는 비켜야 하죠. 결국, C는 D의 자리로. D는 다시 E손님의 자리로 한칸씩 밀려나게 됩니다. 그럼 E는? 의자 옆에 빈 공간에 쭈그려 앉던지, 아니면 새로 의자를 요구해야 하겠죠.
이런 손님이 몇백명 있을경우에 도중에 한사람이 끼어들게 되면 뒤로 밀려야 할 사람의 수가 장난이 아니겠죠? 그런 처리를 내부적으로 해 주는것이 ArrayList객체가 되겠습니다.

 

3. LinkedList

연구실에서 C를 배우고 계시거나, 이미 C단계를 지나신 분들이 이해하기 쉬운 말로 바꾸면 “연결리스트” 입니다. 앞과 뒤의 구조체 주소를 가진 녀석들이 죽 ~ 나열된 모습. 그것이 바로 LinkedList객체의 실체입니다.

사용자 삽입 이미지

LinkedList의 내부구현


이녀석은 순서대로 늘어선 것이 아니라, 다음에 나올 자료의 위치정보만 가지고 있습니다. (앞과 뒤 모두 가진 객체도 있습니다.) 자기가 몇번째인지의 정보는 관심도 없죠.
Vector, ArrayList같이 인덱스정보를 가진 녀석들과의 차이점은 무엇일까요?
바로 추가 / 삭제의 용이함에 있습니다.

사용자 삽입 이미지

LinkedList에서의 데이터 추가


위의 그림에서 알 수 있듯이, 어떤 정보를 도중에 추가하기 위해서 다른 정보들을 뒤로 밀어내는 처리가 필요없습니다. 간단하게 글로 표현해 보면,
A-B-C-D 4명이 눈을 가린채, 서로 손을 잡고 있다고 하죠. 손을 잡기 전에 서로 다음에 오는 사람이 누군지만 확인을 한 상황입니다. 이 상태에서 E라는 사람을 B다음에 세우려면 어떻게 해야 할까요?
간단합니다. B의 손을C가 아닌 E를 잡도록 하고, E의 손이 C를 잡도록 살짝~ 도와만 주면 끝입니다. 요것이 LinkedList내부의 추가 처리입니다.(삭제는 역순임으로 설명은 생략)
데이터의 추가가 빈번하게 일어나는 자료를 처리하기 위한 객체라고 할 수 있습니다. 하지만, 데이터의 검색면에서는 어떨까요?

사용자 삽입 이미지

LinkedList에서의 데이터 검색

조금전의 예 – 손을 마주잡고있는 사람들 A-B-E-C-D 중에서 C를 찾아내서 물어볼것이 있습니다. 이 경우 어떻게 해야 하나요? ArrayList의 경우는 “몇번째 녀석이 C이다. “ 라는 목록을 내부적으로 가지고 있기 때문에 한번에 접근이 가능합니다. ... 만, LinkedList는 그런 목록을 가지고 있지 않기때문에, 최초의 정보A로부터 하나씩 검토를 해 나가야만 합니다.
A에게가서 C의 위치를 물어봐도 A는 B가 어디있는지 밖에 모르기때문에 B에게 가서 다시 C의 위치를 물어봐야 합니다. B는 E의 위치밖에 모르니 E에게 가서 또 물어봐야 하죠. 결국 E가 C의 위치를 알려주게 됩니다만… 확률적으로 n개의 데이터가 들어있을경우에 운이 좋으면 1번에, 운이 나쁜경우는 n번 움직여야만 원하는 데이터를 찾을 수 있게 됩니다. 데이터의 검색에는 그다지 적합하지 않은 녀석이죠.
(자료구조 같은 과목에서 검색패턴에 대한 좋은 이야기를 많이 들을 수 있을거에용~ ^^)

이야기를 정리하면,

  • Vector – 구버젼 호환용. 그다지 사용되지 않음. 동기화 처리가 내부적으로 일어남으로 다른 객체보다 무거움.

  • ArrayList – 배열의 복사에 의한 데이터 저장처리를 내부적으로 행하며, 각 데이터에 대한 인덱스를 가지고 있기때문에 검색이 매우 빠르다. 다만, 많은 데이터의 추가 / 삭제시에는 배열의 복사가 빈번하게 일어나, 성능이 떨어지는 단점이 있다.

  • LinkedList – 다음 자료의 위치정보를 가지며, 내부적인 인덱스는 가지고 있지않다. 데이터의 추가 / 삭제는 위치정보의 수정만으로 가능하기 때문에 많은 정보의 추가 / 삭제처리가 필요할때 유용하다. 다만, 데이터가 많은 경우의 검색시 처음 자료로부터 순차적으로 찾아 나가야 하기 때문에 느려지는 단점이 있다.

아직 설명하지 못한 많은 저장 객체들이 존재합니다만…
일반적으로 사용되는 3가지에 대해서 간단하게 적어보았습니다.
왜 비슷한 기능을 가진 녀석들이 여러개 존재하는걸까~ 라고 생각하신다면 각각의 객체가 가지는 특징과 성능차에 대해서 공부해 보는것도 좋을거라고 생각합니다.

실제로 프로그램이라는건 “동작” 하는건 당연한거죠. 보다 좋은 “성능”을 낼 수 있느냐가 중요하다고 생각합니다.
0.01초의 성능차이도 동작하는 환경에 따라서는 생명선이 될 수도 있으니까요.

모두들 좀 더 재밌게~ 그리고 깊게 공부하시는데 조금이나마 보탬이 되었으면~

하는 마음에서 간단하게 적어보았습니다. ~  m(_ _)m

원본 - http://shagall.tistory.com/36

블로그 이미지

맨오브파워

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

,

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

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

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

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

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

 

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


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


간단한 예제

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

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

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

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

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

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


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

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

int main()
{
    vector<
int> v;

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

    vector<
int>::iterator iter;

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

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

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

int main()
{
    vector<int> v;

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

    vector<int>::iterator iter;

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

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

 

블로그 이미지

맨오브파워

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

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

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

    HANDLE hThread;
    DWORD dwThreadID;

    SOCKADDR_IN servAddr;
    SOCKADDR_IN clntAddr;
    int clntAddrSize;

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

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

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

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

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

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

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

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

    WSACleanup();
    return 0;
}

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

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

    return 0;
}

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

맨오브파워

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

,

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

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

 

#pragma 옵션

  옵션

  설명

 allock_text

 

 comment

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

 init_seg

 

 optimize

 

 auto_inline

 

 component

 

 inline_depth

 

 pack

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

 bss_seg

 

 data_seg

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

 inLine_recursion

 

 pointers_to_members

 

 check_stack

 

 function

 

 intrinsic

 

 setlocale

 

 code_seg

 

 hdrstop

 

 message

 컴파일시 메시지를 출력함

 vtordisp

 

 const_seg

 

 include_alias            

 

 once

 해당 파일이 한번만 포함

 warning

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

 link

 실행화일에 파일을 링크

 

#pragma once

ex> #pragma once

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

 

#pragma pack

ex>

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

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

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

 

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

 

ex>

#pragma pack(1)

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

} TEST_STRUCT, *PTEST_STRUCT;
#pragma pack()

 

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

 

#pragma warning

ex>

 

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

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

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

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

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

제어문

설명

once : 번호

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

default : 번호

원래 설정대로 되돌린다.

disable : 번호

경고를 출력하지 않는다.

error : 번호

경고를 에러로 처리한다.

level : 번호

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

push[,n]

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

pop

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

 

#pragma comment

ex>

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

 

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

  옵션

  설명

 lib

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

 exestr

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

 user

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

 

#pragma data_seg

ex>

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

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

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

 

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

 

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

 

#pragma link

ex>

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

 

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

옵션

 설명

/ALIGN:number

Specifies the alignment of each section

/BASE:{address | @filename,key}

Sets a base address for the program

/COMMENT:["]comment["]

Inserts a comment string into header

/DEBUG

Creates debugging information

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

Creates particular formats of debugging information

/DEF:filename

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

/DEFAULTLIB:library

Searches specified library when resolving external references

/DELAY

Controls the delayed loading of DLLs

/DELAYLOAD

Causes the delayed loading of the specified DLL

/DLL

Builds a DLL

/DRIVER[:UPONLY]

Creates a Windows NT kernel mode driver

/ENTRY:function

Sets the starting address

/EXETYPE:DYNAMIC

Builds a virtual device driver

/EXPORT

Exports a function

/FIXED[:NO]

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

/FORCE[:{MULTIPLE|UNRESOLVED}]

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

/GPSIZE:#

Specifies the size of communal variables for MIPS and Alpha platforms

/HEAP:reserve[,commit]

Sets the size of the heap in bytes

/IMPLIB:filename

Overrides the default import library name

/INCLUDE:symbol

Forces symbol references

/INCREMENTAL:{YES|NO}

Controls incremental linking

/LARGEADDRESSAWARE

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

/LIBPATH:path

Allows the user to override the environmental library path

/LINK50COMPAT

Generates import libraries in Visual C++ Version 5.0 format

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

Specifies the target platform

/MAP

Creates a map file

/MAPINFO:{EXPORTS|FIXUPS|LINES}

Includes the specified information in the map file

/MERGE:from=to

Combines sections

/NODEFAULTLIB[:library]

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

/NOENTRY

Creates a resource-only DLL

/NOLOGO

Suppresses startup banner

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

Controls LINK optimizations

/ORDER:@filename

Places COMDATs into the image in a predetermined order

/OUT:filename

Specifies the output file name

/PDB:filename

Creates a program database (.PDB) file

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

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

/PROFILE

Enables profiling (creates a mapfile)

/RELEASE

Sets the checksum in the .EXE header

/SECTION:name,attributes

Overrides the attributes of a section

/STACK:reserve[,commit]

Sets the size of the stack in bytes

/STUB:filename

Attaches an MS-DOS stub program to a Win32 program

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

Tells the operating system how to run the .EXE file

/SWAPRUN:{NET|CD}

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

/VERBOSE[:LIB]

Prints linker progress messages

/VERSION:major[.minor]

Assigns a version number

/VXD

Creates a virtual device driver (VxD)

/WARN[:level]

Specifies warning level

/WS:AGGRESSIVE

Aggressively trim process memory

옵션

 설명

/ALIGN:number

Specifies the alignment of each section

/BASE:{address | @filename,key}

Sets a base address for the program

/COMMENT:["]comment["]

Inserts a comment string into header

/DEBUG

Creates debugging information

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

Creates particular formats of debugging information

/DEF:filename

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

/DEFAULTLIB:library

Searches specified library when resolving external references

/DELAY

Controls the delayed loading of DLLs

/DELAYLOAD

Causes the delayed loading of the specified DLL

/DLL

Builds a DLL

/DRIVER[:UPONLY]

Creates a Windows NT kernel mode driver

/ENTRY:function

Sets the starting address

/EXETYPE:DYNAMIC

Builds a virtual device driver

/EXPORT

Exports a function

/FIXED[:NO]

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

/FORCE[:{MULTIPLE|UNRESOLVED}]

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

/GPSIZE:#

Specifies the size of communal variables for MIPS and Alpha platforms

/HEAP:reserve[,commit]

Sets the size of the heap in bytes

/IMPLIB:filename

Overrides the default import library name

/INCLUDE:symbol

Forces symbol references

/INCREMENTAL:{YES|NO}

Controls incremental linking

/LARGEADDRESSAWARE

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

/LIBPATH:path

Allows the user to override the environmental library path

/LINK50COMPAT

Generates import libraries in Visual C++ Version 5.0 format

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

Specifies the target platform

/MAP

Creates a map file

/MAPINFO:{EXPORTS|FIXUPS|LINES}

Includes the specified information in the map file

/MERGE:from=to

Combines sections

/NODEFAULTLIB[:library]

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

/NOENTRY

Creates a resource-only DLL

/NOLOGO

Suppresses startup banner

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

Controls LINK optimizations

/ORDER:@filename

Places COMDATs into the image in a predetermined order

/OUT:filename

Specifies the output file name

/PDB:filename

Creates a program database (.PDB) file

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

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

/PROFILE

Enables profiling (creates a mapfile)

/RELEASE

Sets the checksum in the .EXE header

/SECTION:name,attributes

Overrides the attributes of a section

/STACK:reserve[,commit]

Sets the size of the stack in bytes

/STUB:filename

Attaches an MS-DOS stub program to a Win32 program

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

Tells the operating system how to run the .EXE file

/SWAPRUN:{NET|CD}

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

/VERBOSE[:LIB]

Prints linker progress messages

/VERSION:major[.minor]

Assigns a version number

/VXD

Creates a virtual device driver (VxD)

/WARN[:level]

Specifies warning level

/WS:AGGRESSIVE

Aggressively trim process memory


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

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

맨오브파워

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

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

맨오브파워

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

,

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

int → CString

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

블로그 이미지

맨오브파워

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

,
[정정] 확인 결과 Protected된 파일은 appmanager에서도 backup이 불가능하네요...(아래그림참조)
   Rooting을 해야 가능할 것으로 보이며, 현재 Rooting은 Cupcake에서만 가능한 것 같습니다.
   Rooting  관련 자료...
   http://android-dls.com/wiki/index.php?title=Rooting_Android
  http://theunlockr.com/2009/10/15/how-to-root-a-donut-phone-android-1-6/
   참고로 버전업이 되면서 루팅을 계속 막고 있는 중.....
   현재는 1.5에서만 가능한 것으로 보이네요...



-----------------------------------------------------------------
아이폰(iPhone)/아이팟터치(iPod Touch)는 JailBreak를 하면 수많은 유료 어플들을 손쉽게 구해서 사용할 수 있다.

안드로이드 단말은 어떨까?

안드로이드 단말은 애플처럼 앱설치에 대하여 폐쇄적인 정책을 펼치고 있지 않기 때문에
설치 파일인 apk 파일만 구하면 손쉽게 설치가 가능하다.
(단, 외부에서 구한 apk을 설치하려면 setting>applications>unknown sources 에 체크를 해 놓아야 가능하다.)

대신 안드로이드에서의 앱 보호 정책은 Linux가 가지고 있는 유저 권한을 통해 해당 파일의 접근을 막는 방식...
즉, 설치된 앱 파일(apk파일)에 대한 접근을 막으므로써 안드로이드 마켓에서 구매한 앱을 복사하지 못하도록
막고 있다.
여기서 생각해 볼 부분은 아이폰/아이팟터치와 같이 본인의 단말을 Jailbreak 하지 않아도
앱들을  설치할 수 있게 된다는 이야기가 되고, 훨씬 쉽게 앱들이 불법유통될 수 있다는 이야기이다.

개발자들에게는 이부분은 사실 슬픈 이야기이고, 구글이 과연 안드로이드 마켓을 비즈니스의 장으로 보는지
아니면 단순히 안드로이드 플랫폼을 넓히기 위한 용도로 생각하는지를 생각하게 하는 대목이다.

어찌되었든......현실은 현실......
이미 유료 안드로이드 마켓의 어플들이 torrent 등을 통해 돌고 있지만,
직접 추출하는 방법을 아는 것도 나쁘지 않을 듯... 
우선 안드로이드 마켓의 앱 파일(apk 파일)을 추출하는 방법을 정리해 본다.


1) AppManager 설치하기
   안드로이드 마켓에서 'AppManager'라는 어플을 구해서 설치하면 앱파일을 SD로 손쉽게 백업/설치할 수 있다.
  (이런 어플이 안드로이드 마켓에서 버젓이 유통되다나, 구글의 정책이 의심스러운 대목이다...^^")
   백업을 누르면 설치된 모든 어플들을 SD로 백업할 수 있으며, Install을 누르면 반대로 SD에 있는 어플들을
   단말에 설치할 수 있다.
   단, 보호받는 파일들(protected file)은 기본적으로 복사가 이루어지지 않는다.
   (파일 사이즈가 0 로 복사됨)

 

2) 안드로이드 마켓이 설치된 AVD 생성
   우선 일반 단말에서는 Rooting을 통해 SU(Super User) 권한을 얻은 후 AppManager의 백업을 실행하면
   모든 어플의 apk을 SD로 옮길 수 있다.
    단말 루팅 하기
 
   하지만 구지 루팅을 하지 않고 심지어는 안드로이드 단말 없이도 가능한데
   바로 안드로이드 마켓이 포함된 AVD(Android Virtual Device)을 이용하는 방법이다.
  
   이를 위해서는 Eclipse 설치, Android SDK 설치의 복잡한 과정이 필요하지만, 그렇게 어렵지는 않다.
   Android SDK 설치 후 AVD를 생성하는데 이 때 SD카드를 잡아주어야 AppManager에서 백업이 가능하다.(참고)
   그런 다음 AVD에서 안드로이드 마켓에 접속하여 다운받은 모든 어플은 AppManager를 통해 백업할 수 있게 된다.
  


3) AVD의 apk 파일을 PC로 복사하기
  AVD 내 SDCard의 접근은 여러가지 방법이 있고 유틸리티도 있지만,
  개발자라면 Eclipse 내에 있는 DDMS Perspective의 File Explorer를 이용하여 쉽게 PC로 옮길 수 있다.
  왼쪽  Device에서 Emulator 선택하고 File Explorer에서 sdcard\appmanager 폴더 선택 후 우측 상단의
  디스크 모양 아이콘을 눌러서 PC로 파일을 옮기면 apk 파일 추출 끝.......
  
블로그 이미지

맨오브파워

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

,
아이폰에 Jailbreak가 있다면, 안드로이드에는 루팅(Rooting)이 있다...

물론 Jailbreak와는 개념적으로 차이가 있지만, 여러가지로 시스템적으로 막힌 부분들에 대한 접근이 가능해진다.

우선 개념 및 마일스톤/드로이드 루팅 동영상은 "안드로이드펍"에서....

http://www.androidpub.com/116726

그밖의 단말 (HTC G1, Hero, 삼성 Galaxy, 등등)에 대한 Rooting은 "안드로이드 위키"에서

http://android-dls.com/wiki/index.php?title=Main_Page
블로그 이미지

맨오브파워

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

,