c#에서 파일 매핑한 공유 메모리를 읽고 쓰기



using System.Linq;

using System.Text;

using System.Windows.Forms;


using System.IO.MemoryMappedFiles;

using System.IO;



namespace ReadSharedMemory

{

    public partial class frmMain : Form

    {

        public frmMain()

        {

            InitializeComponent();

        }


        // 파일 매핑한 공유 메모리 읽기

        private void btnRead_Click(object sender, EventArgs e)

        {

            MemoryMappedFile mapFile = MemoryMappedFile.OpenExisting(

                "MemoryMapTest", 

                MemoryMappedFileRights.ReadWrite);


            using (Stream view = mapFile.CreateViewStream())

            {

                // stream을 String으로 변환

                view.Position = 0;

                using (StreamReader reader = new StreamReader(view, Encoding.UTF8))

                {

                    this.Text = reader.ReadToEnd();

                }

            }

        }



        // 파일 매핑한 공유 메모리 쓰기

        private void btnWrite_Click(object sender, EventArgs e)

        {

            // Mapping된 file 가져오기

            MemoryMappedFile mapFile = MemoryMappedFile.OpenExisting(

                "MemoryMapTest", 

                MemoryMappedFileRights.ReadWrite);

            

            MemoryMappedViewAccessor accessor = mapFile.CreateViewAccessor();


            // 공유 Memory에 쓰기

            byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(txtMemory.Text + "\0");

            accessor.WriteArray(0, Buffer, 0, Buffer.Length);


            accessor.Dispose();

            mapFile.Dispose();

        }


    }

}



여기에 쓰지는 않았지만 프로세스간 공유 메모리를 읽고 쓸 때에는 Mutex를 사용하여 동시에 읽고 쓰기를 하지 못하게 막아 주어야 된다.


Posted by 떡잎

c#에서 파일 매핑으로 공유한 메모리 읽기

파일 매핑을 다른 언어에서 해도 읽을 수 있음



using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;


using System.IO.MemoryMappedFiles;

using System.IO;


namespace ReadSharedMemory

{

    public partial class frmMain : Form

    {

        public frmMain()

        {

            InitializeComponent();

        }


        private void btnRead_Click(object sender, EventArgs e)

        {

            // MemoryMapTest로 이름붙인 공유 Memory 열기

            var mappedFile = MemoryMappedFile.OpenExisting(

                "MemoryMapTest", 

                MemoryMappedFileRights.ReadWrite);


            // 공유 Memory에서 읽은 것을 Stream으로 받기

            using (Stream view = mappedFile.CreateViewStream())

            {

                // stream을 String으로 변환

                view.Position = 0;

                using (StreamReader reader = new StreamReader(view, Encoding.UTF8))

                {

                    // Textbox에 표시 

                    txtReadMemory.Text = reader.ReadToEnd();

                }

            }

        }

    }

}



파일 매핑을 이용하여 프로세스간 메모리 공유


위의 링크에 있는 소스로 공유 메모리를 만든 것을

상기의 소스로 읽을 수 있음


Posted by 떡잎


C# String에 Null 문자를 더하려면 아래와 같이 하면 된다.


string test = "Null Test" + "\0";




string test = "Null Test" + null; <- 이렇게 쓰면 null 문자로 들어가지 않는다.

Posted by 떡잎
태그 c#,

[C#]추상 Class

2016.07.13 01:09

C#의 추상(Abstract) Class는 

    Interface와 비슷한다.

    Interface에서는 Method 정의만 가능하지만 추상 Class에서는 실제로 Method를 가질 수 있다.

    Interface와 같이 Method의 정의만도 가능하다.

    추상 Class는 반드시 다른 Class에 상속되어 사용된다.


    추상 Class 예제

private void Form1_Load(object sender, EventArgs e)
{
Vehicle a = new Car();
Vehicle b = new Bike();
a.Run();
b.Run();
Close();
}
/// <summary>
/// 추상 Class
/// </summary>
public abstract class Vehicle
{
// Method만 정의 [abstract]
public abstract string getName();
public void Run()
{
MessageBox.Show(getName() + " Run!");
}
}
public class Car : Vehicle
{
// Method만 정의된 것을 구현하는 곳에서는 [override]로 써준다.
public override String getName()
{
return "Car";
}
}
public class Bike : Vehicle
{
public override String getName()
{
return "Bike";
}
}


추상 Class에서 Interface를 사용한 예제

private void Form1_Load(object sender, EventArgs e)
{
Vehicle a = new Car();
Vehicle b = new Bike();
a.Run();
b.Run();
Close();
}
public interface IVehicle
{
string getName();
void Run();
}
/// <summary>
/// 추상 Class
/// </summary>
public abstract class Vehicle : IVehicle
{
public abstract string getName();
public void Run()
{
MessageBox.Show(getName() + " Run!");
}
}
public class Car : Vehicle
{
// Method만 정의된 것을 구현하는 곳에서는 [override]로 써준다.
public override String getName()
{
return "Car";
}
}
public class Bike : Vehicle
{
public override String getName()
{
return "Bike";
}
}










Posted by 떡잎

[C#] Interface 예제

2016.07.09 18:24





우선 Car라는 클래스를 만들고 그 클래스를 사용하는 Run이라는 함수를 만들어 본다.


private void Form1_Load(object sender, EventArgs e)
{
Car a = new Car();
Run(a);
Close();
}
public void Run(Car car)
{
MessageBox.Show("run!");
}
public class Car
{
}


이번에는 Bike라는 클래스를 만들고 그 클래스를 사용하는 Run이라는 함수를 만들어 본다.
Run을 표시하기 위해 Car를 위한 것과 Bike를 위한 것이 두 개가 필요하다.

private void Form1_Load(object sender, EventArgs e)
{
Car a = new Car();
Bike b = new Bike();
carRun(a);
bikeRun(b);
Close();
}
public void carRun(Car car)
{
MessageBox.Show("run!");
}
public void bikeRun(Bike bike)
{
MessageBox.Show("run!");
}
public class Car
{
}
public class Bike
{
}


이런 것을 쉽게 사용하기 위해서는 interface를 사용하면 쉽게 아래와 같이 해결할 수 있다.
Vehicle이라는 interface를 만들어 Car나 Bike는 Vehicle이라는 interface를 가지고 있다는 것을 정의한다.
private void Form1_Load(object sender, EventArgs e)
{
Car a = new Car();
Bike b = new Bike();
Run(a);
Run(b);
Close();
}
public interface Vehicle
{
}
public void Run(Vehicle v)
{
MessageBox.Show("run!");
}
public class Car : Vehicle
{
}
public class Bike : Vehicle
{
}

Interface는 아래와 같이 Method를 정의할 수 있다.
Interface는 실제 함수를 쓸 수는 없고 함수의 형태만 정의할 수 있다.
Interface를 상속하는 클래스에서 Interface에 정의된 함수를 반드시 구현해야만 된다.

private void Form1_Load(object sender, EventArgs e)
{
Vehicle a = new Car();
Vehicle b = new Bike();
Run(a);
Run(b);
Close();
}
public void Run(Vehicle vehicle)
{
MessageBox.Show(vehicle.getName() + " run!");
}
public interface Vehicle
{
String getName();
}
public class Car : Vehicle
{
public String getName()
{
return "Car";
}
}
public class Bike : Vehicle
{
public String getName()
{
return "Bike";
}
}














Posted by 떡잎

[C#] 조건 연산자

2016.05.28 21:19

조건 연산자 

? : 연산자는 3항 연산자(Trinary operator)이다.

첫번째 조건(피연산 함수 : operand)의 결과에 따라 

두번째, 세번째 값을 반환한다.


조건 ? 값 a : 값 b 로 쓰면 

조건이 참이면 값 a를 

조것이 거짓이면 값 b를 반환한다.


첫번째 조건은 bool 형이어야 된다.

두번째와 세번째는 어떤 형이라도 이용할 수 있다.

두번째와 세번째는 같은 형을 써야만 된다.



condition ? a : b

condition이 true이면 a를 false이면 b를 반환한다.


int c = (x < 73) ? true : false;

Posted by 떡잎

C#의 DataGridView에서 가로 Scrollbar가 표시가 안되서 

DataGridView에서 가로 Scrollbar가 표시되는 것과 안되는 것은 몇시간 동안 비교해 봤는데

차이를 발견하지 못했다.


DataGridView의 속성 Scrollbars는 Both로 설정되어 있으나 

이상하게 가로 Scrollbar가 표시되지 않았다.


이유는 "열(Column)"에 있었다.

열을 추가할 때 "고정"이라는 Checkbox가 있다.

이것을 Check하면 열의 속성인 Frozen이 True가 된다.

모든 열의 Frozen이 True가 되어있으면 가로 Scrollbar가 표시되지 않는다.


그럼 왜 가로 Scrollbar가 표시되지않는가

Frozen은 엑셀의 "틀고정"의 "첫열 고정"과 같은 효과가 난다.

Frozen되어 있는 열은 Scrollbar를 움직여도 움직이지 않고 

Frozen이 false되어 있는 열만 Scrollbar를 움직이면 이동하게 된다.



Posted by 떡잎

c#에서 PostgreSQL을 ODBC로 접속할 때 아래의 에러 메시지가 발생했다.


ERROR [IM014] [Microsoft][ODBC 드라이버 관리자] 지정된 DSN은 드라이버와 응용 프로그램 간 아키텍처 불일치를 포함합니다.


원인 

말그대로 아키텍처 불일치다.

이것을 맞추어 주기위해서는

프로젝트의 속성에서 빌드 탭의 일반의 플랫폼 대상을 PostgreSQL의 odbc의 Bit와 맞추어 주면 된다.

PostgreSQL ODBC를 32bit로 했으면 x86으로 64bit로 설치했으면 x64로 하거나

Any CPU로 설정하면 상관없이 동작한다.

Posted by 떡잎

C#에서 PostgreSQL를 ODBC 통해서

Bytea 형의 데이터를 추가하려할 때 밑의 에러가 발생했다.


ERROR: type "lo" does not exist 


인터넷에서 열심히 검색해 보면 이런 에러가 발생했다는 사람만 있지 해결책이 없었다.


그래도 하루종일 찾으니 답은 나왔다.

ODBC 데이터 원본 관리자의

dsn 명의 구성을 보면 Option이 있다.

Option에서 Datasource를 클릭하면 

Advanced Options 창이 표시되고

거기서 Page2를 보면 아래의 설정 항목이 있다.


□bytea as LO


이것을 체크하고 [OK]를 클릭한 뒤 [Save]를 클릭한다

그리고 프로그램을 다시 실행하면 에러가 발생하지 않고 

바이너리 파일을 PostgreSQL의 테이블에 넣을 수 있다.



혹시 나 같은 사람이 또 있을까봐 기록으로 남긴다.

Posted by 떡잎

[C#] WCF 초간단 예제

2014.11.14 20:13



WCF(Windows Communication Foundation) 

나도 잘 몰라서 설명을 잘 못하겠다.

그래도 우선 아래 소스는 이해가 갔다.


프로세스간 통신을 하려면 이전에는 여러가지 방법이 있었다.

그런데 WCF는 그것을 간단하게(?) 해결하여준다.


WCF를 이해하기 위해서는 몇가지 알아야할 개념이 있다.

난 복잡한 것을 잘 모르니까 그냥 내가 이해한 대로 나를 위해 적어본다.


WCF로 프로세스간 통신을 하기위해서는 서버와 클라이언트가 필요하다.

WCF는 서버의 함수들을 클라이언트에서 호출할 수 있게 해준다.


서버의 함수를 클라이언트에서 호출을 할 수 있게 하기 위해서 해야되는 몇가지 작업이 있다.

우선 EndPoint라는 것을 서버에도 클라이언트에도 만들어주어야한다.

어떤 프로세스간 통신을 하더라도 서로 통신을 하기위해 무언가 준비해야된다.

WCF에서 프로세스간 통신을 하기위해서 반드시 필요한 것이 EndPoint이고

EndPont는 서버와 클라이언트간에 통신을 하기위한 양쪽 터널의 끝점같은 것이다.

양쪽 EndPoint를 제대로 설정해야 제대로 통신할 수 있다.


EndPoint는 ABC로 구성되어있다.

A는 Address, B는 Binding, C는 Contract로

Address는 어디에 접속할지를 설정한다.

Binding은 어떻게 접속할지를 설정한다.

Contract는 접속에서 무엇을 할지를 설정한다.


음... 설명하려했는데 이 설명으로 WCF를 이해하는 사람이 있으면 그 사람은 분명히 천재이다. ㅜㅜ

여하튼 WCF는 서버쪽 함수를 클라이언트 쪽에서 쉽게 호출할 수 있게 만들어 준다는 것만을 알아도 WCF를 반이상 안거라고 생각한다.


기본적으로 wCF 관련 자료를 인터넷에서 검색하면 이것저것 설정해야되는 것이 많은데 개인적으로는 아래와 같이 특별히 설정하지 않고 소스에서 Address나 Binding을 처리하는 것이 좋다.



WCF Server 쪽 소스


버튼 두개를 폼에 추가 한다.

솔루션 탐색기의 참조에서 오른쪽 클릭으로 참조 추가를 하여 선택하여

.NET 탭에서 System.ServiceModel을 선택하여 확인 버튼을 누른다.

그리고 소스를 열어 아래 내용들을 추가한다.



using System;
using System.Windows.Forms;

using System.ServiceModel;

namespace wcfSimpleServer
{
    public partial class Form1 : Form
    {
        ServiceHost host;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            // Address 
            string address = "net.tcp://localhost:8080/myAddress";

            // Binding : TCP 사용
            NetTcpBinding binding = new NetTcpBinding();

            // Service Host 만들기
            host = new ServiceHost(typeof(MyService));

            // End Point 추가
            host.AddServiceEndpoint(typeof(IMyContract), binding, address);

            // Service Host 시작
            host.Open();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // Service Host 종료
            host.Close();

        }
    }

    // Client 쪽에서 호출될 함수 Interface
    [ServiceContract]
    public interface IMyContract
    {
        [OperationContract]
        string Hello(string name);
    }

    // 실제로 Client에서 호출될 함수
    public class MyService : IMyContract
    {
        public string Hello(string name)
        {
            return "Hello " + name + "!";
        }
    }
}





WCF 클라이언트 쪽 소스


버튼 한개를 폼에 추가 한다.

솔루션 탐색기의 참조에서 오른쪽 클릭으로 참조 추가를 하여 선택하여

.NET 탭에서 System.ServiceModel을 선택하여 확인 버튼을 누른다.

그리고 소스를 열어 아래 내용들을 추가한다.




using System;
using System.Windows.Forms;

using System.ServiceModel;

namespace wcfSimpleClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.Text = "";

            ChannelFactory<IMyContract> factory = new ChannelFactory<IMyContract>();

            // Address
            string address = "net.tcp://localhost:8080/myAddress";
            factory.Endpoint.Address = new EndpointAddress(address);

            // Binding : TCP 사용
            factory.Endpoint.Binding = new NetTcpBinding();

            // Contract 설정
            factory.Endpoint.Contract.ContractType = typeof(IMyContract);

            // Channel Factory 만들기
            IMyContract channel = factory.CreateChannel();

            // Server 쪽 함수 호출
            string result = channel.Hello("World");

            // Close Channel
            ((ICommunicationObject)channel).Close();

            this.Text = result;
        }

        // Server 쪽 함수 호출용 Interface
        [ServiceContract]
        public interface IMyContract
        {
            [OperationContract]
            string Hello(string name);
        }
    }
}




서버쪽 프로그램 실행하여 버튼1 클릭하고

클라이언트쪽 프로그램 실행하여 버튼1 클릭하면 

클라이언트쪽 폼의 캡션에 "Hello World!"가 출력되면 성공


단언컨데 이 소스보다 간단한 WCF 소스는 별로 없을 것 같다.




Posted by 떡잎
BLOG main image
프로그래밍 공부하면서 써가는 개인 노트 (따라서 여기에 씌여있는 소스의 신빙성을 보장 못함 -.-;;) 이 블로그 보면서 틀린 점이 있으면 꼬옥 알려주세요. by 띠리

공지사항

카테고리

분류 전체보기 (323)
Win32 SDK 초보 (27)
통신관련 (11)
MFC TIP (20)
C/C++ TIP (10)
개발기타 (10)
링크 (2)
견물생심 (24)
이것저것 (8)
용어메모 (3)
데이터베이스 (32)
비주얼 베이직 (10)
하드웨어 (3)
C# (42)
Xcode (3)
델파이 (82)
홈페이지 (5)
MindStorm (0)
낙서 (5)
스크래치 (0)
기타 (6)
아두이노 (1)
라즈베리파이 (2)
안드로이드 (6)
파이썬 (0)
WEB (2)
Total : 944,292
Today : 19 Yesterday : 397