2011-03-19 3 views
2

P/Invoke를 사용하여 네이티브 C++ .dll에 대한 래퍼를 만들려고합니다.P/Invoke problem (불균형 스택)

// .h-file 
CHROMAPRINT_API ChromaprintContext *chromaprint_new(int algorithm);

상기 방법의 구현 :

>// .cpp-file 
struct ChromaprintContextPrivate { 
    int algorithm; 
    Fingerprinter *fingerprinter; 
    vector<int32_t> fingerprint; 
};
:

// .cpp-file 
ChromaprintContext *chromaprint_new(int algorithm) 
{ 
    ChromaprintContextPrivate *ctx = new ChromaprintContextPrivate(); 
    ctx->algorithm = algorithm; 
    ctx->fingerprinter = new Fingerprinter(CreateFingerprinterConfiguration(algorithm)); 
    return (ChromaprintContext *)ctx; 
}

ChromaprintContextPrivate 타입은 구조

.DLL의 소스 코드는 지정된 다음 엔트리 포인트를 갖는다

C# 래퍼 코드 :

를 호출
// .cs-file 
[System.Runtime.InteropServices.DllImportAttribute(
    "libchromaprint.dll", 
    EntryPoint = "chromaprint_new")] 
private static extern System.IntPtr chromaprint_new(int algorithm); 

public static IntPtr Chromaprint_New(ChromaprintAlgorithm algorithm) 
{ 
    // Hardcoded parameter for testing 
    return chromaprint_new(0); // (int)algorithm 
}

은 다음과 MDA의 예외가 발생 :
PInvoke를 기능 'MyProject.ChromaprintWrapper!'MyProject.ChromaprintWrapper.LibChromaPrint :: chromaprint_new '에 대한 호출이 스택 불균형이있다. 관리되는 PInvoke 서명이 관리되지 않는 대상 서명과 일치하지 않기 때문일 수 있습니다. PInvoke 서명의 호출 규칙 및 매개 변수가 대상 관리되지 않는 시그니처와 일치하는지 확인하십시오.

그래서 문제가 무엇인지 이해합니다. 스택의 항목 수가 예상 한 것과 다릅니다. 메서드 매개 변수 int algorithm이 괜찮다고 가정합니다. 비록 반환 형식에 대해 잘 모르겠습니다. 그것은 포인터가 아닌 구조체일까요?

위의 C# 코드는 .h- 파일을 P/Invoke Interop Assistant으로 실행하여 얻었습니다. 반환 형식이 잘못 되었습니까? 그것은 무엇이어야 하는가?

vector<int32_t> fingerprint;의 C# 표현식은 무엇입니까?
(위 ChromaprintContextPrivate 구조를 참조하십시오.)

답변

5

당신은 가장 가능성 호출 규칙을 지정해야보십시오.

는 다음과 같은 시도 : 기본적으로

[System.Runtime.InteropServices.DllImportAttribute("libchromaprint.dll", 
    EntryPoint = "chromaprint_new", 
    CallingConvention=CallingConvention.Cdecl)] 

이는 Windows API를 호출하는 것을 쉽게하기 위해 (효과적으로 STDCALL 인) Winapi를 사용하지만, 이는 일반적으로 대부분의 C++ 라이브러리의 기본이 아니다.

2

이 때문에 매개 변수가 실제로 이 규칙 호출에 전달되는 방식이다.

[DllImport("libchromaprint.dll", CallingConvention = CallingConvention.Cdecl)] 
private static extern IntPtr chromaprint_new(int algorithm); 
0

dllimport 속성에 대한 cdecl 호출 규칙을 선언해야합니다.