2010-06-08 5 views
2

C# 프로그램에서 C++ DLL을 호출해야합니다. 내가의 PInvoke를 사용하여 할 노력하고있어 - 모든 VS2005 \ 2008 년 잘 작동하지만 VS 2010 마이그레이션 후, 나는이 예외가 :VS2010에서 마샬링 구조 포인터

PInvokeStackImbalance가 감지 메시지 : PInvoke를 함수에 대한 호출 ' sampleFunc '가 스택의 불균형을 일으켰습니다. 관리되는 PInvoke 서명이 관리되지 않는 대상 서명과 일치하지 않기 때문일 수 있습니다. 호출 규칙 및 의 PInvoke 서명이 대상 관리되지 않는 시그니처와 일치하는지 확인하십시오.

이 원래 C++ 프로토 타입입니다 : 여기

typedef struct { 
    unsigned short field1; 
    unsigned short field2; 
} sInfo; 

_declspec(dllexport) int sampleFunc(sInfo *info, char *txt); 

와는 C# 코드입니다 :

[StructLayout(LayoutKind.Sequential)] 
    struct SInfo 
    { 
     //[MarshalAs(UnmanagedType.U1)] //also tried with the MarshalAs attr. Didn't help. 
     public ushort field1; 
     //[MarshalAs(UnmanagedType.U1)] 
     public ushort field2; 
    }; 
[DllImport("sampleModule.dll", CharSet=CharSet.Ansi)] 
     public static extern int sampleFunc(ref SInfo info, [MarshalAs(UnmanagedType.LPStr)] string txt); 

내가 대신 심판 SInfo의를 IntPtr로도 그것을 시도했지만, 가지고 동일한 결과 ...

아무 도움도 받으실 수 있습니다.

감사합니다!

답변

2

이것이 어떻게 작동했는지보기가 어렵습니다. C++ 선언은 호출 규칙을 선언하지 않으며 C++ 프로젝트에서/Gz 컴파일 옵션으로 재정의되지 않는 한 기본값은 __cdecl입니다. P/Invoke 마셜 러에게 알려야합니다 :

[DllImport("sampleModule.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] 
    public static extern int sampleFunc(ref SInfo info, string txt); 
1

아마도 구조체를 포장하는 방법과 관련이 있습니다. 기본 팩 크기는 8이므로 너무 많은 바이트가 있다고 생각할 수 있습니다. 그 도움이된다면 (16 비트 정렬) 2 팩 크기 설정을 시도하고 참조 :

또는
[StructLayout(LayoutKind.Sequential, Pack=2)] 

이 같은 오프셋을 지정할 수 있습니다

[StructLayout(LayoutKind.Explicit)] 
public struct struct1 
{ 
    [FieldOffset(0)] 
    public ushort a; // 2 bytes 
    [FieldOffset(2)] 
    public ushort b; // 2 bytes 
} 

Here

포장에 좋은 참고이다
+0

이 구조체에 대한 포인터는 전달 될 수 없습니다. –