블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2309)N
Unity3D (565)N
Programming (471)N
Unreal (4)
Gamebryo (56)
Tip & Tech (182)
협업 (34)
3DS Max (3)
Game (12)
Utility (114)
Etc (92)
Link (31)
Portfolio (19)
Subject (90)
iOS,OSX (37)
Android (12)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (1)
Memories (19)
Interest (37)
Thinking (36)
한글 (26)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (2)
냥이 (9)
육아 (5)
Total1,332,748
Today13
Yesterday299
Statistics Graph

달력

« » 2019.10
    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    

공지사항

태그목록


[링크] http://codingcoding.tistory.com/382


Posted by blueasa
TAG c#, DOUBLE, string

댓글을 달아 주세요

string을 byte[] 배열로 변환? 

string 문자열을 C#의 Char[] 배열로 변경하는 것은 String 클래스의 ToCharArray()라는 메서드를 사용하면 간단하다. 그렇다면, string은 byte[] 배열로 변경하는 것은 가능한가? 만약 가능했다면, string 클래스 안에 ToByteArray() 같은 메서드가 존재할 듯 한데, 이런 메서드는 존재하지 않는다. 왜냐하면, String은 직접 byte[] 변경할 수 없기 때문이다. 먼저 반대의 경우를 생각해 보자. byte[]를 직접 string으로 변경할 수 있는가? 이를 위해 우선 byte[] 가 어떤 Charset을 가지고 인코딩(Encoding) 되었는지 알아야 할 것이다. 이는 아스키, 유니코드, UTF8, GB18030 등 다양한 인코딩 방식에 따라 바이트들이 의미하는 문자가 완전히 다르기 때문이다. 따라서 byte배열을 .NET의 유니코드 string으로 변경하기 위해서는 해당 바이트가 어떤 인코딩인지 알고 이를 유니코드 String으로 변경하게 된다. 동일한 로직으로 문자열을 Byte배열로 변경할 때도 인코딩 방식에 따라 다른 바이트값들을 갖게 된다. 



String을 Byte[]로 인코딩 

문자열을 Byte[] 배열로 변경하기 위해서는 System.Text.Encoding의 인코딩 방식을 지정한 후 GetBytes() 메소드를 호출하면 된다. 예를 들어, 유니코드 인코딩을 사용하여 Byte[]로 변환하는 경우, System.Text.Unicode.GetBytes() 메서드를 호출하고, UTF8 인코딩을 사용하는 경우, System.Text.UTF8.GetBytes() 메서드를 호출하면 된다. 

예제

// String을 Char[]로 변환 
string str = "Hello 한국";
char[] uchars = str.ToCharArray();

// String은 바이트로 직접 변환할 수 없으며,
// Encoding을 통해 변환 가능. 16바이트 생성
byte[] ubytes = System.Text.Encoding.Unicode.GetBytes(str);

// 보다 컴팩트한 UTF8 인코딩. 12바이트 생성
byte[] utf8bytes = System.Text.Encoding.UTF8.GetBytes(str);




Byte[]을 String으로 변환 

Byte[] 배열을 String으로 변환하기 위해서는 바이트로 인코딩했던 동일한 인코더를 사용하여야 한다. 즉, 유니코드 인코더를 사용하여 String은 Byte[]로 변환했었다면 Encoding.Unicode.GetString()을 사용하여 Byte 배열을 문자열로 변경한다. 

예제

using System.Text;

// Byte Array를 String으로 변환 
string s1 = Encoding.Unicode.GetString(uniBytes);
string s2 = Encoding.UTF8.GetString(utf8bytes);




char[]을 String으로 변환 

char[] 배열을 String으로 변환하는 것은 간단하다. C#에서 char는 이미 유니코드이고, string 문자열은 이런 유니코드 문자 요소들의 집합이므로 String 생성자에 문자배열을 직접할당하여 변환할 수 있다. 




BASE64 인코딩 

Byte[] 배열을 웹상에서 전송하기 위해 많이 사용되는 방식으로 BASE64 인코딩을 들 수 있다. 송신 쪽에서는 Convert.ToBase64String(byte[])를 사용하여 바이트들을 BASE64 인코딩된 문자열로 변경하고 String을 전송하게 되고, 수신 쪽에서는 Convert.FromBase64String(string)을 사용하여 BASE64 인코딩된 문자열을 다시 바이트 배열로 변경하여 사용하게 된다. 

예제

// Byte Array를 BASE64 Encoding
string s64 = Convert.ToBase64String(utf8bytes);

// BASE64 인코딩한 String을 다시 Byte Array로
byte[] bytes64 = Convert.FromBase64String(s64);



[출처] http://www.csharpstudy.com/Tip/Tip-string-encoding.aspx

Posted by blueasa
TAG byte[], string

댓글을 달아 주세요

C# 코드

[DllImport("StoreUI_ko_Http.dll", CharSet = CharSet.Auto)]
public static extern void GetPage(string url, out string data);

 

C++ 코드

__declspec(dllexport) void GetPage(BSTR url, BSTR* Result)
 {
         char* pBuffer = NULL;

         HttpConnectGet(url, &pBuffer);
 
         CComBSTR bstrResult = UTF8ToUNICODE(pBuffer);
        *Result = bstrResult.Detach();

        free(pBuffer);
  } 

 

WinXP 환경에서는 위의 코드가 정상적으로 동작하지만

 

Vista에서는 타입변환 오류가 발생되고 만다.

 

스트링 대신에 바이트 타입으로 하면 에러는 발생되지 않지만

 

한글의 경우 유니코드 환경에서 데이타가 다 깨져버린다.

 

해결 방법은 아래처럼 string을 IntPtr로 변경해서 처리하면 된다.

 

IntPtr 는 C#처럼 포인터를 지원하지 않는 어플리케이션과 데이터를 주고 받을때

 

사용하면 편리하다.

 

IntPtr는 C++에서 넘기는 스트링에 대한 포인터 주소값을 저장하게 된다.

 

C# 코드

[DllImport("StoreUI_ko_Http.dll", CharSet = CharSet.Auto)]
 public static extern void GetPage(string url, out IntPtr data);

 

IntPtr param = IntPtr.Zero;  // 초기값 할당 

GetPage("", param);             // C++ 함수 호출

string msg = System.Runtime.InteropServices.Marshal.PtrToStringAuto(param); //string 변환

 

C++ 코드

__declspec(dllexport) void GetPage(BSTR url, BSTR* Result)
 {
         char* pBuffer = NULL;

         HttpConnectGet(url, &pBuffer);
 
         CComBSTR bstrResult = UTF8ToUNICODE(pBuffer);
        *Result = bstrResult.Detach();

        free(pBuffer);
  } 




[출처] C#과 C++ DLL 간의 스트링 데이타 교환|작성자 옆집엉아

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

mouse_event (user32)  (0) 2012.05.21
keybd_event (user32)  (0) 2012.05.21
C#과 C++ DLL 간의 스트링 데이타 교환  (0) 2012.05.14
C# String을 C++ char로 변환  (0) 2012.05.14
Returning Strings from a C++ API to C#  (0) 2012.05.14
SendMessage C# -> C++ with String  (0) 2012.05.09
Posted by blueasa
TAG c#, C++, string

댓글을 달아 주세요



1
2
3
4
5
6
7
8
9
10
using System.Runtime.InteropServices;
 
String strHello = "Hello";
// IntPtr나 System::String^로 넘겨 주면 됨
IntPtr pStr = Marshal.StringToHGlobalUni(strHello );
 
// pStr  사용
 
// 사용 후 메모리 해제
Marshal.FreeHGlobal(pStr);
단순한 코드라 설명을 생략



Posted by blueasa
TAG c#, C++, char, string

댓글을 달아 주세요

1. Introduction.

1.1 APIs that return strings are very common. However, the internal nature of such APIs, as well as the use of such APIs in managed code, require special attention. This blog will demonstrate both concerns.

1.2 I will present several techniques for returning an unmanaged string to managed code. But before that I shall first provide an in-depth explanation on the low-level activities that goes on behind the scenes. This will pave the way towards easier understanding of the codes presented later in this blog.

2. Behind the Scenes.

2.1 Let’s say we want to declare and use an API written in C++ with the following signature :

char* __stdcall StringReturnAPI01();

This API is to simply return a NULL-terminated character array (a C string).

2.2 To start with, note that a C string has no direct representation in managed code. Hence we simply cannot return a C string and expect the CLR to be able to transform it into a managed string.

2.3 The managed string is non-blittable. It can have several representations in unmanaged code : e.g. C-style strings (ANSI and Unicode-based) and BSTRs. Hence, it is important that you specify this information in the declaration of the unmanaged API, e.g. :

[DllImport("<path to DLL>", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string StringReturnAPI01();

In the above declaration, note that the following line :

[return: MarshalAs(UnmanagedType.LPStr)]

indicates that the return value from the API is to be treated as a NULL-terminated ANSI character array (i.e. a typical C-style string).

2.4 Now this unmanaged C-style string return value will then be used by the CLR to create a managed string object. This is likely achieved by using the Marshal.PtrToStringAnsi() method with the incoming string pointer treated as an IntPtr.

2.5 Now a very important concept which is part and parcel of the whole API calling operation is memory ownership. This is an important concept because it determines who is responsible for the deallocation of this memory. Now the StringReturnAPI01() API supposedly returns a string. The string should thus be considered equivalent to an “out” parameter, It is owned by the receiver of the string, i.e. the C# client code. More precisely, it is the CLR’s Interop Marshaler that is the actual receiver.

2.6 Now being the owner of the returned string, the Interop Marshaler is at liberty to free the memory associated with the string. This is precisely what will happen. When the Interop Marshaler has used the returned string to construct a managed string object, the NULL-terminated ANSI character array pointed to by the returned character pointer will be deallocated.

2.7 Hence it is very important to note the general protocol : the unmanaged code will allocate the memory for the string and the managed side will deallocate it. This is the same basic requirement of “out” parameters.

2.8 Towards this protocol, there are 2 basic ways that memory for an unmanaged string can be allocated (in unmanaged code) and then automatically deallocated by the CLR (more specifically, the interop marshaler) :

  • CoTaskMemAlloc()/Marshal.FreeCoTaskMem().
  • SysAllocString/Marshal.FreeBSTR().

Hence if the unmanaged side used CoTaskMemAlloc() to allocate the string memory, the CLR will use the Marshal.FreeCoTaskMem() method to free this memory.

The SysAllocString/Marshal.FreeBSTR() pair will only be used if the return type is specified as being a BSTR. This is not relevant to the example given in point 2.1 above. I will demonstrate a use of this pair in section 5 later.

2.9 N.B. : Note that the unmanaged side must not use the “new” keyword or the “malloc()” C function to allocate memory. The Interop Marshaler will not be able to free the memory in these situations. This is because the “new” keyword is compiler dependent and the “malloc” function is C-library dependent. CoTaskMemAlloc(), and SysAllocString() on the other hand, are Windows APIs which are standard.

Another important note is that although GlobalAlloc() is also a standard Windows API and it has a counterpart managed freeing method (i.e. Marshal.FreeHGlobal()), the Interop Marshaler will only use the Marshal.FreeCoTaskMem() method for automatic memory freeing of NULL-terminated strings allocated in unmanaged code. Hence do not use GlobalAlloc() unless you intend to free the allocated memory by hand using Marshal.FreeHGlobal() (an example of this is give in section 6 below).

3. Sample Code.

3.1 In this section, based on the principles presented in section 2, I shall present sample codes to demonstrate how to return a string from an unmanaged API and how to declare such an API in managed code.

3.2 The following is a listing of the C++ function which uses CoTaskMemAlloc() :

extern "C" __declspec(dllexport) char*  __stdcall StringReturnAPI01()
{
    char szSampleString[] = "Hello World";
    ULONG ulSize = strlen(szSampleString) + sizeof(char);
    char* pszReturn = NULL;

    pszReturn = (char*)::CoTaskMemAlloc(ulSize);
    // Copy the contents of szSampleString
    // to the memory pointed to by pszReturn.
    strcpy(pszReturn, szSampleString);
    // Return pszReturn.
    return pszReturn;
}

3.4 The C# declaration and sample call :

[DllImport("<path to DLL>", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string StringReturnAPI01();

static void CallUsingStringAsReturnValue()
{
  string strReturn01 = StringReturnAPI01();
  Console.WriteLine("Returned string : " + strReturn01);
}

3.5 Note the argument used for the MarshalAsAttribute : UnmanagedType.LPStr. This indicates to the Interop Marshaler that the return string from StringReturnAPI01() is a pointer to a NULL-terminated ANSI character array.

3.6 What happens under the covers is that the Interop Marshaler uses this pointer to construct a managed string. It likely uses the Marshal.PtrToStringAnsi() method to perform this. The Interop Marshaler will then use the Marshal.FreeCoTaskMem() method to free the character array.

4. Using a BSTR.

4.1 In this section, I shall demonstrate here how to allocate a BSTR in unmanaged code and return it in managed code together with memory deallocation.

4.2 Here is a sample C++ code listing :

extern "C" __declspec(dllexport) BSTR  __stdcall StringReturnAPI02()
{
  return ::SysAllocString((const OLECHAR*)L"Hello World");
}

4.3 And the C# declaration and usage :

[DllImport("<path to DLL>", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.BStr)]
public static extern string StringReturnAPI02();

static void CallUsingBSTRAsReturnValue()
{
  string strReturn = StringReturnAPI02();
  Console.WriteLine("Returned string : " + strReturn);
}

Note the argument used for the MarshalAsAttribute : UnmanagedType.BStr. This indicates to the Interop Marshaler that the return string from StringReturnAPI02() is a BSTR.

4.4 The Interop Marshaler then uses the returned BSTR to construct a managed string. It likely uses the Marshal.PtrToStringBSTR() method to perform this. The Interop Marshaler will then use the Marshal.FreeBSTR() method to free the BSTR.

5. Unicode Strings.

5.1 Unicode strings can be returned easily too as the following sample code will demonstrate.

5.2 Here is a sample C++ code listing :

extern "C" __declspec(dllexport) wchar_t*  __stdcall StringReturnAPI03()
{
  // Declare a sample wide character string.
  wchar_t  wszSampleString[] = L"Hello World";
  ULONG  ulSize = (wcslen(wszSampleString) * sizeof(wchar_t)) + sizeof(wchar_t);
  wchar_t* pwszReturn = NULL;

  pwszReturn = (wchar_t*)::CoTaskMemAlloc(ulSize);
  // Copy the contents of wszSampleString
  // to the memory pointed to by pwszReturn.
  wcscpy(pwszReturn, wszSampleString);
  // Return pwszReturn.
  return pwszReturn;
}

5.3 And the C# declaration and usage :

[DllImport("<path to DLL>", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static extern string StringReturnAPI03();

static void CallUsingWideStringAsReturnValue()
{
  string strReturn = StringReturnAPI03();
  Console.WriteLine("Returned string : " + strReturn);
}

The fact that a wide charactered string is now returned requires the use of the UnmanagedType.LPWStr argument for the MarshalAsAttribute.

5.4 The Interop Marshaler uses the returned wide-charactered string to construct a managed string. It likely uses the Marshal.PtrToStringUni() method to perform this. The Interop Marshaler will then use the Marshal.FreeCoTaskMem() method to free the wide-charactered string.

6. Low-Level Handling Sample 1.

6.1 In this section, I shall present some code that will hopefully cement the reader’s understanding of the low-level activities that had been explained in section 2 above.

6.2 Instead of using the Interop Marshaler to perform the marshaling and automatic memory deallocation, I shall demonstrate how this can be done by hand in managed code.

6.3 I shall use a new API which resembles the StringReturnAPI01() API which returns a NULL-terminated ANSI character array :

extern "C" __declspec(dllexport) char*  __stdcall PtrReturnAPI01()
{
  char   szSampleString[] = "Hello World";
  ULONG  ulSize = strlen(szSampleString) + sizeof(char);
  char*  pszReturn = NULL;

  pszReturn = (char*)::GlobalAlloc(GMEM_FIXED, ulSize);
  // Copy the contents of szSampleString
  // to the memory pointed to by pszReturn.
  strcpy(pszReturn, szSampleString);
  // Return pszReturn.
  return pszReturn;
}

6.4 And the C# declaration :

[DllImport("<path to DLL>", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr PtrReturnAPI01();

Note that this time, I have indicated that the return value is an IntPtr. There is no [return : ...] declaration and so no unmarshaling will be performed by the Interop Marshaler.

6.5 And the C# low-level call :

static void CallUsingLowLevelStringManagement()
{
  // Receive the pointer to ANSI character array
  // from API.
  IntPtr pStr = PtrReturnAPI01();
  // Construct a string from the pointer.
  string str = Marshal.PtrToStringAnsi(pStr);
  // Free the memory pointed to by the pointer.
  Marshal.FreeHGlobal(pStr);
  pStr = IntPtr.Zero;
  // Display the string.
  Console.WriteLine("Returned string : " + str);
}

This code demonstrates an emulation of the Interop Marshaler in unmarshaling a NULL-terminated ANSI string. The returned pointer from PtrReturnAPI01() is used to construct a managed string. The pointer is then freed. The managed string remains intact with a copy of the returned string.

The only difference between this code and the actual one by the Interop Marshaler is that the GlobalAlloc()/Marshal.FreeHGlobal() pair is used. The Interop Marshaler always uses Marshal.FreeCoTaskMem() and expects the unmanaged code to use ::CoTaskMemAlloc().

7. Low-Level Handling Sample 2.

7.1 In this final section, I shall present one more low-level string handling technique similar to the one presented in section 6 above.

7.2 Again we do not use the Interop Marshaler to perform the marshaling and memory deallocation. Additionally, we will also not release the memory of the returned string.

7.3 I shall use a new API which simply returns a NULL-terminated Unicode character array which has been allocated in a global unmanaged memory :

wchar_t gwszSampleString[] = L"Global Hello World";

extern "C" __declspec(dllexport) wchar_t*  __stdcall PtrReturnAPI02()
{
  return gwszSampleString;
}

This API returns a pointer to the pre-allocated global Unicode string “gwszSampleString”. Because it is allocated in global memory and may be shared by various functions in the DLL, it is crucial that it is not deleted.

7.4 The C# declaration for PtrReturnAPI02() is listed below :

[DllImport("<path to DLL>", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr PtrReturnAPI02();

Again, there is no declaration for interop marshaling (no use of the [return : ...] declaration). The returned IntPtr is returned as is.

7.5 And a sample C# code to manage the returned IntPtr :

static void CallUsingLowLevelStringManagement02()
{
  // Receive the pointer to Unicde character array
  // from API.
  IntPtr pStr = PtrReturnAPI02();
  // Construct a string from the pointer.
  string str = Marshal.PtrToStringUni(pStr);
  // Display the string.
  Console.WriteLine("Returned string : " + str);
}

Here, the returned IntPtr is used to construct a managed string from an unmanaged NULL-terminated Unicode string. The memory of the unmanaged Unicode string is then left alone and is not deleted.

Note that because a mere IntPtr is returned, there is no way to know whether the returned string is ANSI or Unicode. In fact, there is no way to know whether the IntPtr actually points to a NULL-terminated string at all. This knowledge has to be known in advance.

7.6 Furthermore, the returned IntPtr must not point to some temporary string location (e.g. one allocated on the stack). If this was so, the temporary string may be deleted once the API returns. The following is an example :

extern "C" __declspec(dllexport) char* __stdcall PtrReturnAPI03()
{
  char szSampleString[] = "Hello World";
  return szSampleString;
}

By the time this API returns, the string contained in “szSampleString” may be completely wiped out or be filled with random data. The random data may not contain any NULL character until many bytes later. A crash may ensue a C# call like the following :

IntPtr pStr = PtrReturnAPI03();
// Construct a string from the pointer.
string str = Marshal.PtrToStringAnsi(pStr);




Posted by blueasa
TAG c#, C++, string

댓글을 달아 주세요

[서론]

  이전에 W.O.W 접속유지 프로그램을 만든적은 있지만 그때는 WOW 캡션이 정해져 있었고, 키입력만으로(방향키를 사용했음) 접속유지가 됐기때문에 단순한 키입력 메시지 전달만 하면 끝이었다. 

  다만.. W.O.W 에서 SendMessage를 먹어버려서 PostMessage로 처리했었다.

  (W.O.W 접속유지 프로그램 링크:http://blueasa.tistory.com/527)


  이번에는 서로(현재는 C# -> C++ 만 되는거 보고 정리함.. 나중에 업뎃 할지도..) SendMessage를 보내서 뭔가 일을 꾸밀(?) 수 있게 해보고 싶은마음에 시작.. 물론 양쪽 프로그램은 내가 직접 만든다는 가정하에..

  세상에 선구자는 많으니 역시나..자료를 찾기 시작.. 이전에 간단하나마 만든 것도 있고..

  말재주는 없으니 본론으로 들어가서 그냥 소스 정리..


[사용된 WinAPI 함수 및 중요 키워드]

FindWindow, SendMessage, WM_COPYDATA


[Send : C#]



[Source]

    public class MessageHelper
    {
        [DllImport("User32.dll")]
        private static extern int RegisterWindowMessage(string lpString);

        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        public static extern Int32 FindWindow(String lpClassName, String lpWindowName);

        //For use with WM_COPYDATA and COPYDATASTRUCT
        [DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = false, EntryPoint = "SendMessage")]
        public static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

        //For use with WM_COPYDATA and COPYDATASTRUCT
        [DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = false, EntryPoint = "PostMessage")]
        public static extern int PostMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

        //For use with WM_COPYDATA and COPYDATASTRUCT*
        [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
        private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
        public static extern int SendMessage(int hWnd, int Msg, int wParam, int lParam);

        [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "PostMessage")]
        public static extern int PostMessage(int hWnd, int Msg, int wParam, int lParam);

        [DllImport("User32.dll", EntryPoint = "SetForegroundWindow")]
        public static extern bool SetForegroundWindow(int hWnd);

        public const int WM_USER = 0x400;
        public const int WM_SENDER = WM_USER + 4444;
        public const int WM_COPYDATA = 0x4A;

        //Used for WM_COPYDATA for string messages
        //[StructLayout(LayoutKind.Sequential)] 
        public struct COPYDATASTRUCT
        {
            public int dwData;
            public int cbData;
            //[MarshalAs(UnmanagedType.LPStr)]
            public IntPtr lpData;
        }

        public bool BringAppToFront(int hWnd)
        {
            return SetForegroundWindow(hWnd);
        }

        public int SendWindowsStringMessage(int hWnd, int wParam, string command)
        {
            int result = 0;

            if (hWnd != 0)
            {
                byte[] sarr = System.Text.Encoding.Default.GetBytes(command);
                int len = sarr.Length;

                COPYDATASTRUCT cds = new COPYDATASTRUCT();
                //cds.dwData = (IntPtr)100;
                cds.dwData = 0;
                cds.cbData = len + 1;
                //cds.cbData = Marshal.SizeOf(cds);
                cds.lpData = Marshal.StringToHGlobalAnsi(command);
                //cds.lpData = Marshal.StringToCoTaskMemAnsi(command);

                result = SendMessage(hWnd, WM_COPYDATA, wParam, ref cds);
            }

            return result;
        }

        public int SendWindowsMessage(int hWnd, int Msg, int wParam, int lParam)
        {
            int result = 0;

            if (hWnd != 0)
            {
                result = SendMessage(hWnd, Msg, wParam, lParam);
            }

            return result;
        }

        public int GetWindowID(string className, string windowName)
        {
            return FindWindow(className, windowName);
        }
    }





[Use]


int hWnd = messageHelper.GetWindowID(null, windowCaption);
messageHelper.SendWindowsStringMessage(hWnd, 0, String);



[Receive : C++]


[Source]


WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{  
    switch ( msg )   
    {  
    case WM_COPYDATA:  
        {  
            //Used for WM_COPYDATA for string messages  
            struct COPYDATASTRUCT  
            {  
                int dwData;  
                int cbData;  
                PVOID lpData;  
            };  
  
            COPYDATASTRUCT* cp = (COPYDATASTRUCT*)lParam;  
  
            if( NULL != cp )  
            {  
                String strCommand = "";  
                char szCommand[256] = {0,};  
                  
                memcpy( szCommand, cp->lpData, cp->cbData );  
                  
                if(NULL != szCommand)  
                {  
					/// ToDo  
					/// 여기서 받은 문자열로 할 일 하면 됨.  
					/// dwData는 여기선 의미가 없긴한데 enum이나 int 그대로 써서  
					/// switch문 등으로 분기시켜서 여러가지 다양한 처리를 하려고
					/// 처음 소스 짠사람이 만든 것 같다.  
					/// 다른 일도 분류해서 처리하려면 사용하자.  
                }  
            }  
        }  
        break;  
    }  
}  




[주의]

WM_COPYDATA 는 PostMessage로 날릴 수 없다고 한다. SendMessage를 사용하자.

(상대쪽에서 받기 전에 이쪽에서 메모리 해제 되있으면 AV뜨기때문에..)

참고 링크 : http://lunapiece.net/?mid=Tips&listStyle=webzine&document_srl=3780&sort_index=readed_count&order_type=desc


P.s. 마음대로 되지 않고 삽질도 많이해서 여기저기 쓰이지 않는 주석이 남아있긴 하지만.. 삽질기념(?) 그냥 냅두기..

       하도 검색하고 다녀서 참조한 곳을 다 찾기엔 좀 걸리거나 빼먹을 수 도 있을 것 같다. 출처를 찾으러 가야지..



[참조]

http://boycook.wordpress.com/2008/07/29/c-win32-messaging-with-sendmessage-and-wm_copydata/

http://kofmania.tistory.com/45

http://xarfox.tistory.com/45

http://jacking.tistory.com/134

http://www.hoons.kr/board.aspx?Name=qacshap&Mode=2&BoardIdx=10465&Key=&Value=

http://lunapiece.net/?mid=Tips&listStyle=webzine&document_srl=3780&sort_index=readed_count&order_type=desc

- 그 외 못 적은 곳은.. 죄송합니다..;;



Posted by blueasa

댓글을 달아 주세요

1
2
3
4
5
6
7
8
9
10
11
#include<string>
#include<iostream>

int main()
{
const char* charString= "Eggs on toast.";
 std::string someString(charString);

 std::cout << someString;
 return 0;
}

1
2
char *cStr = "C++";
std::string Str = std::string(cStr);


출처 :  http://www.cplusplus.com/forum/general/41912/
Posted by blueasa

댓글을 달아 주세요

Summary

Enums are a powerful construction in C# and other programming languages when you are working with finite sets such as fruits, days of the week or colors. Visual Studio's Intellisense is very nice with Enums because it lists all the options for the programmer to choose from. But quite often you want to print enums, compare int values, or serialize an enum--and then you have to do some conversions.The following method may be run in the code-behind file of an ASPX page where you have added a Label control named lblOutput. However, this technique will work in any C# program, not just ASP.NET.

Example: Convert string to Enum instance

public void EnumInstanceFromString()
{
   // The .NET Framework contains an Enum called DayOfWeek.
   // Let's generate some Enum instances from strings.

   DayOfWeek wednesday = 
      (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "Wednesday");
   DayOfWeek sunday = 
      (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "sunday", true);
   DayOfWeek tgif = 
      (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "FRIDAY", true);

   lblOutput.Text = wednesday.ToString() 
      + ".  Int value = " + ((int)wednesday).ToString() + "<br>";
   lblOutput.Text += sunday.ToString() 
      + ".  Int value = " + ((int)sunday).ToString() + "<br>";
   lblOutput.Text += tgif.ToString() 
      + ".  Int value = " + ((int)tgif).ToString() + "<br>";

}
The Enum.Parse method takes two or three arguments. The first is the type of the enum you want to create as output. The second field is the string you want to parse. Without a third input, the case of the input string must match an enum instance or the conversion fails. But the third input indicates whether to ignore case. If true, than wEdNEsDAy will still get converted successfully.

Example: Output

Wednesday. Int value = 3
Sunday. Int value = 0
Friday. Int value = 5

출처 :  http://www.cambiaresearch.com/articles/47/convert-string-to-enum-instance

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

Nullable 형식 사용  (0) 2012.01.19
MeasureString(문자열 길이 체크)  (0) 2012.01.17
Convert String To Enum Instance  (0) 2011.12.16
문자열이 숫자 값을 나타내는지 확인  (0) 2011.12.16
Operator Overloading in C#  (2) 2011.12.05
Force property update in propertygrid  (0) 2011.11.29
Posted by blueasa
TAG enum, string

댓글을 달아 주세요

Array -> String

Programming/C# / 2011.05.09 02:12

요새 c#으로 삽질중이다.

 

오늘은 배열로 한 한시간 가까이 날려 먹은거 같은데;;

 

Array라는 타입이 있다. 모든 배열의 기초 클래스란다

요넘을 String[]로 옮기고 싶은 거다...

 

즉...

Array Buffer = new Array[0];

이런 녀석이 있다면

String[] szBuffer = Buffer;

이 짓을 하고 싶다는 거지;;

 

한참을 해맸지만 결론은 간단했다.

 

String[] szBuffer = (String)Buffer;

 

허탈하네 - _-;;



[출처]
 C#에서 배열|작성자 시네루진

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

C# 관련 정보 사이트[MKEXDEV.NET]  (0) 2011.09.13
Processing Global Mouse and Keyboard Hooks in C#  (0) 2011.05.13
Array -> String  (0) 2011.05.09
SaveFileDialog  (0) 2011.03.25
DataGridView to XML  (0) 2011.03.23
ToolTip 사용하기  (0) 2011.02.11
Posted by blueasa
TAG array, string

댓글을 달아 주세요

흔히 string 객체 중 null일 때 참조하여
exception을 내는 경우를 방지하기 위하여
아래와 같이 코딩하는 경우가 있는데
매번 이와 같이 하는 것도 귀찮은 일이다.

string str = null;
...

if(str != null && str.length > 0)
{
...
}

그러나 위와 같은 check를 하는 함수가 string class에 static function으로 존재한다.
모르면 손발이 고생 ;;
string.IsNullOrEmpty(str)
Posted by blueasa
TAG empty, null, string

댓글을 달아 주세요