首页 新闻 会员 周边

c#调用c++dll时 在结构体上出现问题

1
悬赏园豆:30 [已解决问题] 解决于 2010-08-23 11:56

c++结构体的声明

 

typedef struct _PREAMP_STAT
{
BYTE Freqency;
//
BYTE FPGAvsn1; //
BYTE FPGAvsn2; //
BYTE CPUvsn1; //
BYTE CPUvsn2; //
BYTE Hardwarevsn1; //
BYTE Hardwarevsn2; //
BYTE SerialNum[6]; /
BYTE CellVotage[2]; //
BYTE CellState; //
  BYTE MaxConfig; //
BYTE ChoiceState[9];//
BYTE Reserves[38]; //
} PREAMP_STAT,*PPREAMP_STAT;//sizeof(PREAMP_STAT) = 64

c++中的引用:

ReadAmpInfo(PPREAMP_STAT pPreAMPStat);

我在c#中定义的结构:

[StructLayout(LayoutKind.Sequential)]
public struct PPREAMP_STAT
{
[MarshalAs(UnmanagedType.U1)]
public Byte Freqency; //
[MarshalAs(UnmanagedType.U1)]
public Byte FPGAvsn1; //
[MarshalAs(UnmanagedType.U1)]
public Byte FPGAvsn2; //
[MarshalAs(UnmanagedType.U1)]
public Byte CPUvsn1; //
[MarshalAs(UnmanagedType.U1)]
public Byte CPUvsn2; //
[MarshalAs(UnmanagedType.U1)]
public Byte Hardwarevsn1; //
[MarshalAs(UnmanagedType.U1)]
public Byte Hardwarevsn2; //
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public Byte[] SerialNum; //
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public Byte[] CellVotage; //
[MarshalAs(UnmanagedType.U1)]
public Byte CellState; //
[MarshalAs(UnmanagedType.U1)]
public Byte MaxConfig; //
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
public Byte[] ChoiceState;//
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 38)]
public Byte[] Reserves; //
} //sizeof(PREAMP_STAT) = 64

导入dll的语句:

[DllImport(@"lib\HardUsb.dll")] public static extern bool ReadAmpInfo( PPREAMP_STAT pPreAMPStat);//

在c#中的引用:

PPREAMP_STAT myPPREAMP_STAT = new PPREAMP_STAT();
bool aa= ReadAmpInfo(myPPREAMP_STAT);//就是这句错误

出现的错误是:对 PInvoke 函数“xxxx!xxxxx.mainform::ReadAmpInfo”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。

请大侠们务必指教!我好郁闷!

为森的主页 为森 | 小虾三级 | 园豆:579
提问于:2010-08-22 01:31
< >
分享
最佳答案
0

结构体不能这么传,你只能传指针:

如下:

PPREAMP_STAT myPPREAMP_STAT = new PPREAMP_STAT();

byte[] buf = new byte[Marshal.Sizeof(myPPREAMP_STAT)];

IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buf,0);

MarShal.StructureToPtr(myPPREAMP_STAT,ptr,true);

bool aa=ReadAmpInfo(ptr);//

 

另外StructLayout 有个 Pack  属性,是设置字节对齐,你问下你用那个dll的字节对齐方式,然后把 Pack 设置

为相同的大小。

收获园豆:30
Launcher | 高人七级 |园豆:45045 | 2010-08-22 22:33
谢谢您的建议请问我在引用一个c++:HARDUSBDLL_API BOOL Begin(int iSize); 是直接导入后用Begin(2);或者int aa=2;begin(aa);还是报错,错误仍然是出现的错误是:对 PInvoke 函数“xxxx!xxxxx.mainform::ReadAmpInfo”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。 请您务必指教!
为森 | 园豆:579 (小虾三级) | 2010-08-23 02:06
忘记给分了
为森 | 园豆:579 (小虾三级) | 2010-08-23 02:06
@文楚:倒是是 Begin 不对,还是 ReadAmpInfo 不对?
Launcher | 园豆:45045 (高人七级) | 2010-08-23 09:13
都不对也!!! 今天卸载了vs2010 装上vs2008begin就好了,不知道是vs的问题还是nf4.0的问题。
为森 | 园豆:579 (小虾三级) | 2010-08-23 11:40
已经确定是nf4.0的问题,现在将项目改成nf3.5平台还是vs2010其他一切不变暂时没有发现任何问题。
为森 | 园豆:579 (小虾三级) | 2010-08-23 11:57
P/Invoke Interop Assistant - Overview 这个工具很好用。谢谢浪客dandy
为森 | 园豆:579 (小虾三级) | 2010-08-23 11:58
其他回答(1)
1

你这个是自己写的么,你应该用生成工具生成了再改

PInvoke自己写的话是很容易出错的

浪客Dandy | 园豆:479 (菜鸟二级) | 2010-08-22 14:00
我用了P/Invoke Interop Assistant - Overview 还是不行,您知道有什么更好的工具吗?谢谢
支持(0) 反对(0) 为森 | 园豆:579 (小虾三级) | 2010-08-23 02:03
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册