C#에서 C의 structure 쓰기/읽기.

카二리의 이미지

WINAPI의 function에서 parameter로 받는 struct를 C#에서 쓰려고 합니다.

UINT SendInput(
    UINT nInputs,
    LPINPUT pInputs,
    int cbSize
);

위 function을 쓰려고 하는대요.

여기서 문제 되는게 PInputs라는 녀석인대.

typedef struct tagINPUT { 
  DWORD type; 
  union {MOUSEINPUT mi; 
            KEYBDINPUT ki;
            HARDWAREINPUT hi;
           };
  }INPUT, *PINPUT;

typedef struct tagMOUSEINPUT {
    LONG dx;
    LONG dy;
    DWORD mouseData;
    DWORD dwFlags;
    DWORD time;
    ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT;


이렇게 생긴 INPUT 이란 녀석의 array 입니다.

이걸 C#에서 저 위의 function에 넘겨 주려 하니, struct 안에 struct가 union 으로 있는 녀석의 배열을 어찌 해서 넘겨 줘야 할지..

이전에 GetCursorPos라는 function의 parameter로 struct를 넘겨서 그걸 다시 읽어서 cursor의 x,y좌표를 읽을때는 byte 배열을 넘긴후에 System.BitConverter.ToInt64 method를 이용해서 long의 길이인 4비트씩 짤라서 해석을 했는대요

보낼때도 비슷하게 해보려고 했지만 전의 GetCursorPos에서 쓴 struct와 function이 간단하게

BOOL GetCursorPos(
    LPPOINT lpPoint
);

typedef struct tagPOINT { 
  LONG x; 
  LONG y; 
} POINT, *PPOINT; 

//C#
[DllImport("user32")]
public extern static bool GetCursorPos( byte[] lpPoint);

이렇게 되어 있어서 쉽게 해석이 가능 했는대.

저 위의 경우에 도저히 내부에 union으로 struct가 있는 strcut의 배열을 어떻게 해야 할지...

혹시 저런식으로 byte array로 직접 넘기는것이 아닌.. 좀더 세련된 방법이 없을까요?

C#에도 struct가 있지만. 똑같은 구조로 만들어서 보냈더니 안가더군요..

어떻게 해야 할까요?

meteors의 이미지

C에서만 사용할 수 있도록 만들었기 때문에 C#에서 쓰는 것은 어렵다고 보입니다.

그 내용에 access 하는 부분을 C++에서 class로 만들고 결과물로 나온 DLL을 C#에서 불러 쓰는게 가장 깨끗한 선택이라고 봅니다.

카二리의 이미지

흠 제가 C#을 배우는 과정이고 방법을 배우려는 것이지 퍼포먼스 등을 따질려는것이 아니기 때문에

native compile이 되는 언어로 만든후 가져다 쓰지 않으려 합니다.

그리고 질문후 계속 검색을 하다가

http://lyon-smith.org/blogs/john/articles/240.aspx

이와 같은 비슷한 글을 발견 했습니다.

하지만 union이나 structure의 array등 기존에 byte[] 어레이로 해결하기 까다로운 부분을 해결할 방법이 명시적으로 안나와 있고 CLR 코드를 볼줄조차 모르기에 저 글을 읽어도 현재 방법을 제대로 찾지 못하고 있습니다.

퍼포먼스나.. 다른걸 따지려는게 아니라 이와 같은걸 해결하는 방법을 찾으려고 합니다. :wink:

C# 내부에서 해결할 방법은 없을까요?[/url]

새 생각 :)

카二리의 이미지

MSDN을 마구 뒤져서 알아냈습니다.

참고로 이하 코드는 모노에서도 동일하게 쓸수 있을것 같습니다.

	[StructLayout( LayoutKind.Sequential )]
	public struct MOUSEINPUT{
		public int dx;
		public int dy;
		public uint mouseData;
		public uint dwFlags;
		public uint time;
		public IntPtr dwExtraInfo;
	}
	
	[StructLayout( LayoutKind.Sequential )]
	public struct INPUT{
		public uint type;
		public MOUSEINPUT mi;
	}

	[DllImport("user32.dll")]
	public extern static uint SendInput(uint nInputs,[In, Out]INPUT[] pInputs, int cbsize);

포인트는
[StructLayout( LayoutKind.Sequential )]
[In, Out]
입니다.

참조 URL 은

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconstructssample.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconunionssample.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconarrayssample.asp

입니다.

결국 2일 삽질해서 나왔군요 -_-;; 혼자 질문하고 혼자 대답하기; :twisted:

새 생각 :)

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.