问题描述
Com的idl[id(4),helpstring("methodStructureTest")]HRESULTStructureTest(MyPointa);结构申明typedefstructPoint{intx;inty;}MyPoint;C#中结构包装,函数包装[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]publicstructPoint{[MarshalAs(UnmanagedType.I4)]publicintx;[MarshalAs(UnmanagedType.I4)]publicinty;}publicclassTestStructureDll{[DllImport("DataTypeTest2.dll",CallingConvention=CallingConvention.StdCall,EntryPoint="StructureTest")]publicstaticexternvoidStructureTest2([In,MarshalAs(UnmanagedType.Struct)]Pointa);}函数调用Pointa=newPoint();a.x=1;a.y=2;intx=1;inty=2;TestStructureDll.StructureTest2(a);就出现错误对PInvoke函数“CApp_DllTest!CApp_DllTest.TestStructureDll::StructureTest2”的调用导致堆栈不对称。原因可能是托管的PInvoke签名与非托管的目标签名不匹配。请检查PInvoke签名的调用约定和参数与非托管的目标签名是否匹配。我看了很久,没明白哪里错了,请高手指点~看过Knight94(愚翁)回答的两个问题,我也没弄好~谢谢!(高分相送)
解决方案
解决方案二:
帮顶
解决方案三:
数据类型错了,Win32的Long并不对应.NET下的Long。检查一下数据类型
解决方案四:
应该是参数问题,int换成byte看看,c里的int是8位,而c#里的int=int32是32位,用UnmanagedType.I4强行转成为8位不知道会不会出问题publicstructPoint{[MarshalAs(UnmanagedType.I4)]publicbytex;[MarshalAs(UnmanagedType.I4)]publicbytey;}
解决方案五:
Int32
解决方案六:
然后c#里的byte是8位
解决方案七:
自己对应一下BOOL=System.Int32BOOLEAN=System.Int32BYTE=System.UInt16CHAR=System.Int16COLORREF=System.UInt32DWORD=System.UInt32DWORD32=System.UInt32DWORD64=System.UInt64FLOAT=System.FloatHACCEL=System.IntPtrHANDLE=System.IntPtrHBITMAP=System.IntPtrHBRUSH=System.IntPtrHCONV=System.IntPtrHCONVLIST=System.IntPtrHCURSOR=System.IntPtrHDC=System.IntPtrHDDEDATA=System.IntPtrHDESK=System.IntPtrHDROP=System.IntPtrHDWP=System.IntPtrHENHMETAFILE=System.IntPtrHFILE=System.IntPtrHFONT=System.IntPtrHGDIOBJ=System.IntPtrHGLOBAL=System.IntPtrHHOOK=System.IntPtrHICON=System.IntPtrHIMAGELIST=System.IntPtrHIMC=System.IntPtrHINSTANCE=System.IntPtrHKEY=System.IntPtrHLOCAL=System.IntPtrHMENU=System.IntPtrHMETAFILE=System.IntPtrHMODULE=System.IntPtrHMONITOR=System.IntPtrHPALETTE=System.IntPtrHPEN=System.IntPtrHRGN=System.IntPtrHRSRC=System.IntPtrHSZ=System.IntPtrHWINSTA=System.IntPtrHWND=System.IntPtrINT=System.Int32INT32=System.Int32INT64=System.Int64LONG=System.Int32LONG32=System.Int32LONG64=System.Int64LONGLONG=System.Int64LPARAM=System.IntPtrLPBOOL=System.Int16[]LPBYTE=System.UInt16[]LPCOLORREF=System.UInt32[]LPCSTR=System.StringLPCTSTR=System.StringLPCVOID=System.UInt32LPCWSTR=System.StringLPDWORD=System.UInt32[]LPHANDLE=System.UInt32LPINT=System.Int32[]LPLONG=System.Int32[]LPSTR=System.StringLPTSTR=System.StringLPVOID=System.UInt32LPWORD=System.Int32[]LPWSTR=System.StringLRESULT=System.IntPtrPBOOL=System.Int16[]PBOOLEAN=System.Int16[]PBYTE=System.UInt16[]PCHAR=System.Char[]PCSTR=System.StringPCTSTR=System.StringPCWCH=System.UInt32PCWSTR=System.UInt32PDWORD=System.Int32[]PFLOAT=System.Float[]PHANDLE=System.UInt32PHKEY=System.UInt32PINT=System.Int32[]PLCID=System.UInt32PLONG=System.Int32[]PLUID=System.UInt32PSHORT=System.Int16[]PSTR=System.StringPTBYTE=System.Char[]PTCHAR=System.Char[]PTSTR=System.StringPUCHAR=System.Char[]PUINT=System.UInt32[]PULONG=System.UInt32[]PUSHORT=System.UInt16[]PVOID=System.UInt32PWCHAR=System.Char[]PWORD=System.Int16[]PWSTR=System.StringREGSAM=System.UInt32SC_HANDLE=System.IntPtrSC_LOCK=System.IntPtrSHORT=System.Int16SIZE_T=System.UInt32SSIZE_=System.UInt32TBYTE=System.CharTCHAR=System.CharUCHAR=System.ByteUINT=System.UInt32UINT32=System.UInt32UINT64=System.UInt64ULONG=System.UInt32ULONG32=System.UInt32ULONG64=System.UInt64ULONGLONG=System.UInt64USHORT=System.UInt16WORD=System.UInt16WPARAM=System.IntPtr
解决方案八:
你的问题主要就是COMInterop过程中的数据封送问题。楼上有人已经给出了正确的答案。但是如果只获得答案,不知道原理,以后遇到了此类问题还是不知道如何下手。如果你想系统学习如何进行数据封送,我推荐你阅读刚刚出版的新书:《精通.NET互操作P/Invoke,C++Interop和COMInterop》,这本书的第5,6章“COMInterop”,详细介绍了COMInterop,非常详细,我就是读完后才搞清楚COMInterop中的封送处理等问题。该书的官方网站:豆瓣网信息: