2010-12-06 5 views
2

dll을 작동 시키려고합니다.마샬링 C++ int *에서 C#

DLL은 C++로 작성되었으며 int *를 C#에 전달해야합니다. 나는이 일을하기 위해 며칠을 보냈고 실패했다. 내가 무엇이 잘못되었는지 알 수 없기 때문에 나는 머리카락을 꺼내기 시작했다. 나는 모든 것을 시도했다. 나는 C++에 익숙하지 않아서 C#에서 문제가 발생할 수 있습니다 ...

dll에서 정상적으로 읽었지만 반환 된 값이 올바르지 않습니다. 내가 입력을 제거하고, 나는 단지 테스트 배열을 통해 얻으려고 노력하고있다. 나는 C++에서 사용하고있는 기능은 다음과 같습니다

extern "C" EAGLE128DLL_API int* encryptFunc() 
{ 
    //return encrypt(x, Q); 

    int t[128]; 

    for(int i = 0; i < 128; i++) 
    { 
     t[i] = 5; 
    } 

    return t; 
}; 

C# 코드 나는 다음과 같이이 기능은 전화를 걸 때 사용 : 출력 배열 내에서

[DllImport("C:\\Users\\Leon\\Documents\\Visual Studio 2010\\Projects\\Eagle128DLL\\Release\\Eagle128DLL.dll")] 
      public static extern IntPtr encryptFunc(); 
    ... 

IntPtr outputPtr = encryptFunc(); 
int[] output = new int[128]; 

Marshal.Copy(outputPtr, output, 0, 128); 

값은 모두 5의를해야한다. 하지만 내가 얻을 수있는 것은 : 16187392, 16190224..etc (not 5 's)

+0

[return : MarshalAs] 속성을 사용하여 IntPtr 대신 Int []를 반환하고 마샬 러가 작업을 수행 할 수있게해야합니다. [반환 : MarshalAs (UnmanagedType.LPArray, SizeConst = 128) ] 공공 정적 extern int [] encryptFunc(); – jeffora

답변

2

C++ 코드에 오류가 있습니다. 스택에 저장된 변수에 대한 포인터를 반환하고 (t[128]은 임시 변수 일뿐) 작동하지 않습니다. encryptFunc이 반환되는 즉시 call stack will be unwound과 변수 t[128]이 삭제됩니다.

static int t[128]; 
... 
return t; 

정적 변수가 더 이상 스택에 저장되지 않으며 함수의 끝을 살아남을 것입니다 :

코드가 될 필요가있는 경우 재입 또는 스레드 안전, 당신은 단순히 t[128] 정적 만들 수 있습니다 .

+0

haha ​​cant는 그것이 그렇게 단순하다고 믿습니다. 가장 큰 머리카락 끌어 당기는 사람은 언제나 오하이오처럼 단순해서 생각조차하지 않을 것입니다 ... 정말 고마워요 !! – Leon

+0

정적 배열에서 delete []를 사용하여 메모리에서 제거해야한다고 추측합니다. – Leon

+0

아니요, 그러지 마세요. 힙에 할당 된 메모리의 delete [] 만 사용하십시오 (new 사용). 정적 변수를 삭제할 필요가 없습니다. –

2

당신의 문제는 C 함수의 스택에 로컬로 선언 된 값을 반환하려고한다는 것입니다.

가장 좋은 것은 C 함수에 미리 할당 된 배열을 전달하는 것입니다.이 배열은 함수가 만든 데이터를 받아서 호출자에게 다시 반환합니다.