2013-08-28 1 views
2

내 코드에서 올바르게 알았습니다. 구조가 16 진수로 고정되어 있고, 컴파일 타임에 알았습니다. 배열의 크기를 알지 못하고 C에서 C#으로 호출합니다.

struct CONSOLE_SCREEN_BUFFER_INFOEX 
{ 
    int arraySize; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)] 
    public int ColorTable[]; 
} 

는, C 함수 응답에서 arraySize를 얻을 적당한 크기 COLORTABLE 배열, COLORTABLE에 응답 넣어 결과를 초기화 :

struct CONSOLE_SCREEN_BUFFER_INFOEX 
{ 
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] 
public int ColorTable[]; 
} 

는하지만 내가 필요로하는 것은이 구조를 가질 수있을 것입니다.

가능한지 확실하지 않고 지금 당장 조사를하고 있으며 모든 의견을 환영합니다.

+0

이 그 필드를 선언하는 적절한 방법이없고, 그것은 [MarshalAs (UnmanagedType.ByValArray, SizeConst = 16)] 공중 INT [] COLORTABLE으로 수행되어야한다. 어느 것이 더 많은 로프를 줄지 만 * Size * 필드에 의존 할만큼 충분하지는 않습니다. 커스텀 마셜 러를 작성해야합니다. –

+0

안녕하세요 Hans, 맞습니다. 지금 당장이 작업을 수행하고 있습니다. [MarshalAs (UnmanagedType.ByValArray, SizeConst = 16)], 혼란을 피하기 위해 Jon의 코드와 비슷하게 만들었습니다. 하지만 이제는 요청이 [MarshalAs (UnmanagedType.ByValArray, SizeConst = 0)]이고 크기를 변경하면 크기를 알 수있을 때 맞춤 marshaller가 정확히 내가 흥미 롭다. – inside

+0

이 질문은 맞춤식으로 더 좋을 것입니다. 이러한 모든 추가 필드는 토론을 위해 불필요합니다. 한스 (Hans)는 맞습니다. 여기에 '안전하지 않은'것이 필요하지 않습니다. Jon은 아마도 이것을 '고정 된'것을 설명하는 방법으로 선택했을 것입니다. 그러나 ByValArray는 올바른 접근 방식입니다. 맞춤 마샬 러를 사용할 수 있습니다. 아니면'IntPtr','Marshal.AllocHGlobal','Marshal.PtrToStructure','Marshal.Copy'로 할 수 있습니다. –

답변

2

Marshal 클래스를 사용하여 수동 마샬링을 사용하면 쉽게이를 수행 할 수 있습니다. 예를 들어

[DllImport(@"MyLib.dll")] 
private static extern void Foo(IntPtr structPtr); 

private static IntPtr StructPtrFromColorTable(int[] colorTable) 
{ 
    int size = sizeof(int) + colorTable.Length*sizeof(int); 
    IntPtr structPtr = Marshal.AllocHGlobal(size); 
    Marshal.WriteInt32(structPtr, colorTable.Length); 
    Marshal.Copy(colorTable, 0, structPtr + sizeof(int), colorTable.Length); 
    return structPtr; 
} 

private static int[] ColorTableFromStructPtr(IntPtr structPtr) 
{ 
    int len = Marshal.ReadInt32(structPtr); 
    int[] result = new int[len]; 
    Marshal.Copy(structPtr + sizeof(int), result, 0, len); 
    return result; 
} 

static void Main(string[] args) 
{ 
    int[] colorTable = new int[] { 1, 2, 3 }; 
    IntPtr structPtr = StructPtrFromColorTable(colorTable); 
    try 
    { 
     Foo(structPtr); 
     colorTable = ColorTableFromStructPtr(structPtr); 
    } 
    finally 
    { 
     Marshal.FreeHGlobal(structPtr); 
    } 
} 
+0

감사합니다! 내일 그것을 검토 할 것이다! 좋아! – inside

+0

@Stanislav이 질문에 관심이 있으실 것입니다 : http://stackoverflow.com/questions/18498452/how-do-i-write-a-custom-marshaler-which-allows-data-to-flow-from-native -to-manag? lq = 1 –