2014-01-10 3 views
1

INTPTR로 구조 변환 :을 IntPtr 대신 I 사용다음 I 클래스 정의가

typedef struct 
{ 
    void *p; 
    int len; 
} OUR_MEM_STR; 

바이트 [] :

[StructLayout(LayoutKind.Sequential)] 
public class OUR_MEM_STR 
      { 
       public byte[] p; 
       public int len; 
      }; 

이 아래 C 구조의 등가 (고화질) 인 멤버 p를 입력하십시오. 왜냐하면 그것은 thorughout C# 프로젝트에 사용되었습니다.

I 렌 = 10, p = I 새로운 바이트가에게 INTPTR을 만들고 싶어 [10]

가지는 객체 (OBJ)를 정의 하였다. 어떻게 개체의 크기를 구합니까?

IntPtr pObj = Marshal.AllocHGlobal(obj.len + sizeof(int)); 
Marshal.StructureToPtr(obj, pObj, true); 

내가 무엇을했는지보십시오. 그것은 너무 하드 코딩 된 것 같습니다. 내가 아래 발췌 문장을한다면;

IntPtr pObj = Marshal.AllocHGlobal(Marshal.SizeOf(obj)); 

obj.p 4의 크기를 반환하지 (10) 때문에 바이트 배열에 대한 포인터를 가리키는 취한 메모리는 4 바이트이기 때문에이 잘못된 크기를 반환 하.

더 좋은 방법이 있습니까?

+0

복제하려는 구조체의 C 정의를 표시 할 수 있습니까? – JaredPar

+0

@JaredPar, 나는 질문을 편집 –

+0

그래서, 만약 내가 IntPtr pObj = Marshal.AllocHGlobal (Marshal.SizeOf (obj)); 잘못된 매개 변수를 사용하면 괜찮을까요? –

답변

3

반환 값은 p포인터이고 4 바이트를 사용합니다.

이 방법으로두면 두 개의 메모리가 할당됩니다. 마셜 러는 배열에 대한 메모리를 할당했습니다. 그것은 COM 어레이 유형 인 SAFEARRAY를 만들었습니다. 당신의 C 코드가 그렇게 행복하지는 않을 것이다.

[StructLayout(LayoutKind.Sequential)] 
public class OUR_MEM_STR { 
    public IntPtr p; 
    public int len; 
}; 

을 그리고 p을 할당 Marshal.AllocHGlobal (10)를 사용하여이 대신처럼 선언합니다. 다시 정리하는 것을 잊지 마십시오.

이 (가)이 (가) StructToPtr()에 전달되지 않으면 AllocHGlobal()에 의해 할당 된 메모리가 초기화되지 않습니다. 그러면 무작위로 프로그램이 중단됩니다. false을 전달해야합니다.

+0

고마워! C# 가비지 수집이 자동으로 정리되지 않습니까? –

+1

아니요, 관리되지 않는 메모리를 할당했습니다. Marshal.FreeHGlobal()을 두 번 호출하는 것은 어려운 요구 사항입니다. 이 코드는 * struct *를 사용하여 멈춘 후에 발생해야합니다. –

+0

수정하십시오. Lil에 의해 Lil 나는 주인공이다 pinvoke. SO와 같은 ppl 덕분에 –

관련 문제