2010-04-07 9 views
2

C#의 안전하고 관리 된 코드에서 포인터 배열 (void **)을받는 C API에서 함수를 호출하고 싶습니다.C#에서 IntPtrs의 배열을 마샬링

해당 관리되는 IntPtr 개체 배열이 있지만 MSDN의 설명서에 보급 된 Marshal 메서드가 올바른 내용으로 관리되지 않는 메모리 블록에 IntPtr을 제공하기에 충분하지 않은 것처럼 보입니다.

'Marshal.AllocHGlobal'을 사용하여 IntPtr을 얻은 다음 'Marshal.Copy'를 사용하여 올바른 내용을 할당하려고했지만 IntPtr 배열에 대해 함수가 오버로드되지 않은 것 같습니다.

가장 좋은 방법은 무엇입니까?

미리 감사드립니다.

답변

4

P/Invoke 마샬 러가 이미이 작업을 수행하므로 도움이 필요하지 않습니다. 그냥 배열로 함수 인수를 선언

[DllImport("blah.dll")] 
private static extern void SomeFunction(IntPtr[] array); 

그냥 경우 : 당신이 여기에 안전하지 않은 키워드를 사용하지 않지만, 그것에 대해 안전 아무것도 없다. C 코드는 할당 한 블록의 끝을 지나쳐 쓸 때 힙을 쉽게 손상시킬 수 있습니다.

3

배열을 IntPtr []로 전달하면 IntPtr은 기본적으로 void *로 정렬됩니다. 아니요 은 안전하지 않아야합니다.

[DllImport("containingFoo.dll")] 
public static extern void foo(IntPtr[] ptr); 

...

// some floats 
float[] fpa = {7.2F, 2.3F, 3.3F, 4.5F, 6.5F}; 
// allocate unmanaged for float[] fpa and int (length of array) 
IntPtr fptr = Marshal.AllocHGlobal(fpa.Length * 
Marshal.SizeOf(typeof(float))); 
IntPtr iptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int))); 
// set length of array 
Marshal.WriteInt32(iptr, fpa.Length); 
// copy the array 
Marshal.Copy(fpa, 0, fptr, fpa.Length); 
// strore both pointers in IntPtr[] 
IntPtr[] pptr = {fptr, iptr}; 
// call foo passing the IntPtr[] to C 
foo(pptr); 

// C/C++ // 의 PInvoke를 사용할 때 기본 규칙을 호출 stdcall 규칙을주의 !!!!

void __stdcall foo(void** data) 
{ 
float * fa = (float*)*data; // first element points to float array 
int *ip = (int*)data + 1; // pointer to next element in void array 
int *pp = (int*)*ip; // get pointer to int 
for (int i = 0; i < *pp ; i++) 
{ 
printf("\t: %f\n", *fa++); 
} 
} 
관련 문제