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

카테고리

분류 전체보기 (2737)
Unity3D (817)
Programming (474)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (228)
협업 (58)
3DS Max (3)
Game (12)
Utility (136)
Etc (96)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (53)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday
04-25 09:56

C# Keywords

Programming/C# / 2014. 5. 13. 15:37

출처 : http://msdn.microsoft.com/en-us/library/x53a06bb.aspx


C# Keywords

Visual Studio 2013
14 out of 17 rated this helpful Rate this topic

Keywords are predefined, reserved identifiers that have special meanings to the compiler. They cannot be used as identifiers in your program unless they include @ as a prefix. For example, @if is a valid identifier but if is not because if is a keyword.

The first table in this topic lists keywords that are reserved identifiers in any part of a C# program. The second table in this topic lists the contextual keywords in C#. Contextual keywords have special meaning only in a limited program context and can be used as identifiers outside that context. Generally, as new keywords are added to the C# language, they are added as contextual keywords in order to avoid breaking programs written in earlier versions.

Contextual Keywords

A contextual keyword is used to provide a specific meaning in the code, but it is not a reserved word in C#. Some contextual keywords, such as partial and where, have special meanings in two or more contexts.



반응형
Posted by blueasa
, |




ScreenWipe_For_CSharp.zip





참조 : http://wiki.unity3d.com/index.php?title=CrossFade


출처 : http://answers.unity3d.com/questions/166898/screenwipe-crossfade-with-c.html

반응형

'Unity3D > Script' 카테고리의 다른 글

ClipboardHelper  (0) 2014.05.15
유니티 코루틴 깊이 알고 재미있게 쓰기.  (0) 2014.05.09
A simple cross fade shader for Unity  (0) 2014.04.22
어플을 내렸을때, 어플을 종료할때의 처리  (3) 2014.04.04
Unity Singleton  (0) 2014.03.24
Posted by blueasa
, |

Sorting

Programming/C# / 2013. 10. 2. 17:46


링크 : http://support.microsoft.com/kb/320727/ko

링크 : http://www.codeproject.com/Articles/42839/Sorting-Lists-using-IComparable-and-IComparer-Inte

링크 : http://www.dotnetperls.com/sort-string-array

반응형
Posted by blueasa
, |

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# 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
, |



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
, |

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
, |

[서론]

  이전에 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
, |

오디오 재생을 위해
.net framework에 기본으로 포함되어 있는
System.Media.SoundPlayer를 사용중 몇가지 문제점을 발견하여
대체할 수 있는 놈들을 아래와 같이 조사해 보았습니다.
최종적으로는 오픈소스인 NAudio 를 선택하였구요..
써보니.. 좋네요.. ^^

1. DirectX

   - http://www.alvas.net/alvas.audio.aspx 
   - Microsoft.DirectX.AudioVideoPlayback.dll 을 참조추가
   - .net 1.x기준으로 만들어진듯함. 2.0~3.5에서는 초기 로딩시 Loader Lock Exception 발생
   - Loader Lock 예외처리 : http://hanury.net/wp/archives/549  
   - .net 4.0에서는 실행안됨

2. System.Media.SoundPlayer

   - 동시에 여러개의 사운드를 재생할 수 없음
   - A가 재생중, B를 멈추면 A도 멈춤
   - 사용이 쉬움
   - Stream 사용이 가능하여 음원을 Resource에 넣어서 배포 가능
   - .wav 파일만 지원함
   

3. Alvas.Net

   - 상용
   - http://www.alvas.net/alvas.audio.aspx 
   - 기능 : Records audio, Plays audio, Set up mixer controls, Edits audio, Converts audio


4. NAudio

   - 무료, 오픈소스
   - http://naudio.codeplex.com/ 
   - Play back audio, Decompress audio, Record audio, Mix and manipulate audio streams 등..
   - Stream 사용가능, wav 및 mp3 사용가능


반응형
Posted by blueasa
, |

Library File :




DEVIL.NET has been included in the main DEVIL distribution

Go to the DevIL image library website for the entire package. Here after you can find the older releases and, when a new one will get released, the newer ones.

WHAT IS DEVIL.NET ?

I’ve written a small wrap around the DevIL image library .

As for the .NET viewer, this is a “2 hour project” – that is a project I’ve written in 2 hours before going to sleep.. so no warranty is included! ;)

NOTE : This project is intentionally minimalist. If you want a more complete wrapper over DevIL, have a look at the Tao.Framework.

It allows any .NET program (VB.NET, C#, etc) to open and save files in all formats supported by the DevIL library. Also it opens them as System.Drawing.Bitmap objects, so that it works optimally with existing code.

As now it supports loading in bmp cut dcx dds ico gif jpg lbm lif mdl pcd pcx pic png pnmpsd psp raw sgi tga tif wal act pal and Doom graphics

And saving in : bmp dds jpg pcx png pnm raw sgi tga tif pal

Using it is simple.

As an example you can load/save a picture in a picturebox using (C# and VB.NET):


// C#
System.Drawing.Bitmap bmp = DevIL.DevIL.LoadBitmap(filename);
pictureBox1.Image = bmp;

‘ VB.NET
Dim bmp as System.Drawing.Bitmap
bmp = DevIL.DevIL.LoadBitmap(filename)
pictureBox1.Image = bmp

And you can save the picturebox image using :


// C#
System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)pictureBox1.Image;
DevIL.DevIL.SaveBitmap(filename, bmp);

‘ VB.NET
Dim bmp as System.Drawing.Bitmap
bmp = pictureBox1.Image
DevIL.DevIL.SaveBitmap(filename)
LICENSE & VERSION
C++.NET (Managed C++) Source is included and released under a choice of BSD or LGPL license. You can contact me for additional licensing options if you need them. Binaries are provided in the package, compatible with every version of .NET Framework (from 1.0 to 3.0).
SAMPLES
You can download samples for DevIL.NET library. The sample program is a small utility which acts as a viewer and a converter of image files, written in both C# and VB.NET.

RELEASE NOTES
I’ve done many tries and it seems the stride in .NET framework for 32bit images is always 4*width. While this can be expected, effectively the stride could have any value. As now the code relies heavily on a predictable stride to optimize memory copies.. please report me any bug (marcoPLEASEDELTHIS@mastropaolo.com), especially if you think a different stride is in place.

UPDATES

  • March 4th, 2007 : Release Version 1.3
  • July 12th, 2005 : Fixed a minor bug in initialization, uploaded samples
  • August 23th, 2005 : Release Version 1.1
  • December 8th, 2004 : Release Version 1.0

VERSION 1.1 CHANGES

  • Fixed a bad bug when loading non true color images (above all GIFs)
  • Implemented a new LoadBitmapAndScale which allows for the bitmap to be scaled directly in DevIL.NET
  • Started to implement some error handling…
  • note: From version 1.1, DevIL.NET may require ILU.dll to be installed in addition to DevIL.DLL. Since having an additional DLL is always a burden, ILU.dll is loaded dinamically and it’s not required unless the scale/resize feature is used ;)

VERSION 1.2 CHANGES

  • Support for VS2005, .NET Framework 2.0 on x86 platforms
  • NOTE : When using Devil.NET 1.2 on VS2005, remind to set your projects to use the x86 CPU. Otherwise the program may fail to run on x64 platforms.

VERSION 1.3 CHANGES

  • Fixed the infamous vertical flip bug
  • The v-flip can be done both in ILU code or .NET framework (depending on whether ILU.DLL has been loaded or not; you can load ILU.DLL either by loading an image with scale options or through the LoadILU method).
  • A DevIL.NET2.DLL exists. This is a framework 2.0/3.0 only version which is just a bit smaller than the “every” framework version.

Download Library Version 1.3
Download Library Version 1.2
Download Library Version 1.1
Download Library Version 1.0
Download VC++ sources and project
Download C# and VB.NET Samples
View the source online

반응형
Posted by blueasa
, |

최근 만들고 있는 프로그램에 사용할 음성재생 라이브러리를 이것저것 살펴보다가..

WMPLib, MBroMP3, DirectX.AudioVideoPlayback 이렇게 3가지를 놓고 상당한 고민을 했습니다.

이것저것 살펴본결과, 직접 구현하면서 사용하기에는 DirectX.AudioVideoPlayback이 수월해보여 이녀석으로 결정했습니다.

기념으로 DirectX.AudioVideoPlayback을 사용해서 간단하게 음성파일 재생을 구현해 보도록하겠습니다.

 

Microsoft.DirectX.AudioVideoPlayback을 사용하면 생각보다 간편하게 기능을 구현할 수 있습니다만..

.NET 1.1에서 구현된 녀석들을 .NET 2.0에서 사용하면 등장하는 문제인 LoaderLock 버그가 여기에도 존재합니다.

차근차근 구현하고.. 이 LoaderLock이 등장하지 않도록 하는 것까지 오늘은 알아보도록 하겠습니다.

 

우선 가장 먼저 해야할 일은 이 녀석을 사용하기 위한 준비과정이 되겠죠?

아래 그림처럼 참조추가의 .NET탭에서 Microsoft.DirectX.AudioVideoPlayback 항목을 선택해줍니다.


 

 

그러면 솔루션 탐색기에서 추가된 참조를 확인할 수 있습니다.

이녀석을 더블클릭해서 개체 브라우저로 잠시 우리가 사용할 녀석을 확인해보도록하지요.

 


이처럼 설명도 모두 나와있으니, 참고하시면 되겠습니다.

기본적으로 필요한 메소드와 프로퍼티는 모두 제공하고 있으므로 생각보다 쉬울 것 같습니다.

 

간단하게 폼이 로드되면 재생되는 코드를 만들어 볼까요?


그림과 같이 사용하시면 해당 경로의 음악파일을 자동으로 재생합니다. 두 번째 인자를 false로 주면 자동 재생은 안되죠.

이 외에 필요시에는 Play()나 Open()메소드를 이용하시면 되겠습니다.

 

이렇게 했지만.. 아마도 막상 시작을하면 LoaderLock예외가 발생하면서 프로그램이 중단될 것입니다.

아래와 같이 하면.. 완전히 해결하는 것은 아니지만, 프로그램이 죽지않게 할 수 있습니다.

(제가 알고 있는 완벽하게 해결하는 방법은 .Net Framework 1.1을 설치하는 것입니다.)

 

디버그 -> 예외 -> Managed Debugging Assistant -> LoaderLock의 Throw속성을 체크해제합니다.


 

 

LoaderLock예외를 이렇게 처리하고나면 이녀석을 컨트롤과 연결시켜서 사용자의 요구에 따라서 동작하는

재생프로그램을 만들고 싶으실지도 모르겠습니다.

재생시간이나 볼륨을 TrackBar와 연동시키고 싶다면.. TrackBar를 생성하고 TrackBar의 ValueChanged이벤트가

발생했을 때, 해당 Value를 받아와서 수행시키게하고... 재생, 중지등에 대한 적절한 이미지를 만들어 주고, 이 녀석들에 대한 Click이벤트를 Stop(), Pause()등의 메소드들과 연결하시면 되겠습니다.

 

 

문제는 재생중에 재생시간에 대한 TrackBar를 움직여야 한다는 점인데요. 이 부분은 쓰레드로 해결을 하는 수밖에 없겠지요.

Invoke를 사용해서 한다면 특별한 문제점은 없을거라고 생각합니다만..

처음에 언급했던 너무 완벽한 버그인 LoaderLock때문에 문제점이 발생하지 않을지는 저도 해보아야 알것 같습니다.

이 부분은 해보고 빠른 시일내에 이 글을 수정하는 식으로 업데이트하도록 하겠습니다.

 -> 확인결과 이상없이 잘 수행됩니다.

 

 

 

이로써 간단하게 음악파일을 재생할 수 있는 기능을 살펴보았습니다.


 
[출처] 〃C# DirectX.AudioVideoPlayback를 이용한 음성파일 재생.|작성자 Chuls

반응형
Posted by blueasa
, |