C#调用COM组件时的结构类型数据封送问题,报PInvoke 签名错误

curieloveyou 2009-04-02 09:20:05
Com 的idl
[id(4), helpstring("method StructureTest")] HRESULT StructureTest(MyPoint a);
结构申明
typedef struct Point
{
int x;
int y;
}MyPoint;
C#中 结构包装,函数包装
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Point
{
[MarshalAs(UnmanagedType.I4)]
public int x;
[MarshalAs(UnmanagedType.I4)]
public int y;
}
public class TestStructureDll
{
[DllImport("DataTypeTest2.dll",CallingConvention=CallingConvention.StdCall,EntryPoint="StructureTest")]
public static extern void StructureTest2([In,MarshalAs(UnmanagedType.Struct)]Point a);
}
函数调用
Point a = new Point();
a.x = 1;
a.y = 2;
int x=1;
int y=2;
TestStructureDll.StructureTest2(a);
就出现错误 对 PInvoke 函数“CApp_DllTest!CApp_DllTest.TestStructureDll::StructureTest2”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
我看了很久,没明白哪里错了,请高手指点~ 看过Knight94(愚翁)回答的两个问题,我也没弄好~ 谢谢!(高分相送)
...全文
153 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaomiyinerzhou 2009-05-13
  • 打赏
  • 举报
回复
你的问题主要就是COM Interop过程中的数据封送问题。楼上有人已经给出了正确的答案。但是如果只获得答案,不知道原理,以后遇到了此类问题还是不知道如何下手。

如果你想系统学习如何进行数据封送,我推荐你阅读刚刚出版的新书:《精通.NET互操作P/Invoke,C++Interop和COM Interop》,这本书的第5,6章“COM Interop”,详细介绍了COM Interop,非常详细,我就是读完后才搞清楚COM Interop中的封送处理等问题。


该书的官方网站:
www.interop123.com

豆瓣网信息:
http://www.douban.com/subject/3671497/
zzxap 2009-04-02
  • 打赏
  • 举报
回复
自己对应一下
BOOL=System.Int32
BOOLEAN=System.Int32
BYTE=System.UInt16
CHAR=System.Int16
COLORREF=System.UInt32

DWORD=System.UInt32
DWORD32=System.UInt32
DWORD64=System.UInt64
FLOAT=System.Float
HACCEL=System.IntPtr

HANDLE=System.IntPtr
HBITMAP=System.IntPtr
HBRUSH=System.IntPtr
HCONV=System.IntPtr
HCONVLIST=System.IntPtr

HCURSOR=System.IntPtr
HDC=System.IntPtr
HDDEDATA=System.IntPtr
HDESK=System.IntPtr
HDROP=System.IntPtr

HDWP=System.IntPtr
HENHMETAFILE=System.IntPtr
HFILE=System.IntPtr
HFONT=System.IntPtr
HGDIOBJ=System.IntPtr

HGLOBAL=System.IntPtr
HHOOK=System.IntPtr
HICON=System.IntPtr
HIMAGELIST=System.IntPtr
HIMC=System.IntPtr

HINSTANCE=System.IntPtr
HKEY=System.IntPtr
HLOCAL=System.IntPtr
HMENU=System.IntPtr
HMETAFILE=System.IntPtr

HMODULE=System.IntPtr
HMONITOR=System.IntPtr
HPALETTE=System.IntPtr
HPEN=System.IntPtr
HRGN=System.IntPtr

HRSRC=System.IntPtr
HSZ=System.IntPtr
HWINSTA=System.IntPtr
HWND=System.IntPtr
INT=System.Int32

INT32=System.Int32
INT64=System.Int64
LONG=System.Int32
LONG32=System.Int32
LONG64=System.Int64

LONGLONG=System.Int64
LPARAM=System.IntPtr
LPBOOL=System.Int16[]
LPBYTE=System.UInt16[]
LPCOLORREF=System.UInt32[]

LPCSTR=System.String
LPCTSTR=System.String
LPCVOID=System.UInt32
LPCWSTR=System.String
LPDWORD=System.UInt32[]

LPHANDLE=System.UInt32
LPINT=System.Int32[]
LPLONG=System.Int32[]
LPSTR=System.String
LPTSTR=System.String

LPVOID=System.UInt32
LPWORD=System.Int32[]
LPWSTR=System.String
LRESULT=System.IntPtr
PBOOL=System.Int16[]

PBOOLEAN=System.Int16[]
PBYTE=System.UInt16[]
PCHAR=System.Char[]
PCSTR=System.String
PCTSTR=System.String

PCWCH=System.UInt32
PCWSTR=System.UInt32
PDWORD=System.Int32[]
PFLOAT=System.Float[]
PHANDLE=System.UInt32

PHKEY=System.UInt32
PINT=System.Int32[]
PLCID=System.UInt32
PLONG=System.Int32[]
PLUID=System.UInt32

PSHORT=System.Int16[]
PSTR=System.String
PTBYTE=System.Char[]
PTCHAR=System.Char[]
PTSTR=System.String

PUCHAR=System.Char[]
PUINT=System.UInt32[]
PULONG=System.UInt32[]
PUSHORT=System.UInt16[]
PVOID=System.UInt32

PWCHAR=System.Char[]
PWORD=System.Int16[]
PWSTR=System.String
REGSAM=System.UInt32
SC_HANDLE=System.IntPtr

SC_LOCK=System.IntPtr
SHORT=System.Int16
SIZE_T=System.UInt32
SSIZE_=System.UInt32
TBYTE=System.Char

TCHAR=System.Char
UCHAR=System.Byte
UINT=System.UInt32
UINT32=System.UInt32
UINT64=System.UInt64

ULONG=System.UInt32
ULONG32=System.UInt32
ULONG64=System.UInt64
ULONGLONG=System.UInt64
USHORT=System.UInt16

WORD=System.UInt16
WPARAM=System.IntPtr
wartim 2009-04-02
  • 打赏
  • 举报
回复
然后c#里的byte是8位
zzxap 2009-04-02
  • 打赏
  • 举报
回复
Int32
wartim 2009-04-02
  • 打赏
  • 举报
回复
应该是参数问题,int换成byte看看,c里的int是8位,而c#里的int=int32是32位,用UnmanagedType.I4强行转成为8位不知道会不会出问题

public struct Point
{
[MarshalAs(UnmanagedType.I4)]
public byte x;
[MarshalAs(UnmanagedType.I4)]
public byte y;
}
zzxap 2009-04-02
  • 打赏
  • 举报
回复
数据类型错了,Win32的Long并不对应.NET下的Long。

检查一下数据类型
FlyBee 2009-04-02
  • 打赏
  • 举报
回复
帮顶

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧