2013-04-15 3 views
2

C로 작성된 DLL 파일이 있습니다. C# 코드에서 C DLL을 사용하려고합니다. C 프로그램 메소드는 int **를 리턴합니다. int ** in c 및 int [] [] in C#는 동일합니까?int ** 및 int [] [] C#에서 동일합니까?

C 프로그램에서 값을 반환하는 중에 오류가 발생했습니다.

C 방법

__declspec(dllexport) int someMethod 
    (
     size_t *foo, 
     int **bar 
    ) 
    { 
     *foo = 10; 
     **bar = 10; 
    } 

내 C# 코드 C의 int**와 C#의 int[][] 바이너리 수준에서 개념 비슷하지만 다른이

[DllImport(@"my.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true, BestFitMapping = true, EntryPoint = "someMethod")] 
    public unsafe static extern int someMethod 
    (
     out Int16 foo, 
     [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(JaggedArrayMarshaler))] 
     out int[][] bar 
    ); 
+3

일부 코드를 보여줄 수 있습니까? 어떤 오류가 발생하고 있습니까? – GrandMasterFlush

+0

'**'는 포인터를 가리키는 포인터입니다. '[] []'은 배열의 배열, 즉 "들쭉날쭉 한"배열입니다. 나는 그것이 같은 것을 의미하지는 않는다는 느낌을 가지고있다 :) – walther

+0

간단한 콘솔 앱. DLLImport 문을 사용하면 도움이 될 것입니다 –

답변

1

:

  • int** 포인터이다 포인터, 비 관리 힙 메모리의 원시 데이터
  • int[][]은 관리되는 배열에 대한 관리되는 참조의 관리되는 배열에 대한 관리되는 참조입니다. 각각은 원시 데이터 대신 배열의 헤더 (길이가 포함 된)를 가리 킵니다.

C#의 마샬링 (marshal)이 가장 쉬운 방법이 무엇인지 알 수 없습니다. SAFEARRAY을 중첩 할 수 있습니까? 그렇다면 아마도 C# 배열에 쉽게 매핑 될 것입니다.

확실한 해결책은 C#으로 돌아 가기 전에 int**cli::array<cli::array<int>^>^ (뾰족한 데이터 복사 포함)으로 변환하기 위해 C++/CLI DLL을 두 코드 사이의 접착제로 사용하는 것입니다.

+0

"이진 수준이 다르지만"- 어떻게 그렇게됩니까? – SecurityMatt

+0

@SecurityMatt 방금 정보를 추가했습니다. – Medinoc

0

C 함수 프로토 타입이 올바른지 가정, 난 당신이 C#을 측면에 thusly 히 선언해야한다고 생각 :

public unsafe static extern int someMethod 
(
    out Int16 foo, 
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0, ArraySubType=UnmanagedType.I2)] 
    out int[] bar 
); 

는 그러나, 나는 메모리 누수를 우려하고있다. 관리되지 않는 배열을 어떻게 할당 해제 할 수 있는지 잘 모르겠습니다.

+0

System.Runtime.InteropServices.MarshalDirectiveException : '매개 변수 # 2'를 (를) 마샬링 할 수 없습니다. ByRef 배열 매개 변수에 SizeParamIndex를 사용할 수 없습니다. 이 오류가 발생합니다. – mmpatel009

+0

이것은 표준 marshaller가 out 매개 변수로 marchal 배열을 사용할 수 없음을 의미합니다. – Medinoc

관련 문제