C#调用WIN 32 DLL参数传递的问题(结构,指针等)????

dy2712 2006-07-29 02:35:34
DLL的代码如下:
typedef struct cdm_cashunit
{
USHORT usNumber;
USHORT usType;
char cUnitID[5];
char cCurrencyID[3];
ULONG ulValues;
ULONG ulInitialCount;
ULONG ulCount;
ULONG ulMinimum;
ULONG ulMaximum;
USHORT usStatus;
} CDMCASHUNIT, * LPCDMCASHUNIT;

typedef struct cdm_cu_info
{
USHORT usTellerID;
USHORT usCount;
LPCDMCASHUNIT *lppList;
} CDMCUINFO, * LPCDMCUINFO;

DLLEXPORT int __stdcall GetCashUnitInfo(LPCDMCUINFO CassUnitInfo)

C#调用如下:

unsafe public class ClassCDM
{
public ClassCDM()
{

}

[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct cdm_cashunit
{
public UInt16 usNumber;
public UInt16 usType;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=5 )]
public char[] cUnitID;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=3 )]
public char[] cCurrencyID;
public UInt32 ulValues;
public UInt32 ulInitialCount;
public UInt32 ulCount;
public UInt32 ulMinimum; public UInt32 ulMaximum;
public UInt16 usStatus;
}

[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct cdm_cuinfo
{
public UInt16 usTellerID;
public UInt16 usCount;
public IntPtr[] lppList; //这个地方,我拿不准应该是IntPtr,还是IntPtr[]
}



[DllImport("cdm.dll")]
private static extern int GetCashUnitInfo(ref cdm_cuinfo cassinfo);


public cdm_cuinfo gCass = new cdm_cuinfo();

public int GetCassInfo()
{
int i,ret;

gCass.lppList=new IntPtr[8];
IntPtr[] buffer=new IntPtr[8];
cdm_cashunit[] cuinfo=new cdm_cashunit[8];


for(i=0;i<8;i++)
{
cuinfo[i].cCurrencyID=new char[3];
cuinfo[i].cUnitID=new char[5];

buffer[i]= Marshal.AllocCoTaskMem( Marshal.SizeOf(cuinfo[i] ));
Marshal.StructureToPtr( cuinfo[i], buffer[i], false );
gCass.lppList[i] = buffer[i];

}



ret=GetCashUnitInfo(ref gCass);
for(i=0;i<8;i++)
{
Marshal.FreeCoTaskMem( buffer[i] );

}

return ret;

}
}

调用的时候就会出现异常:
未处理的“System.Runtime.InteropServices.COMException”类型的异常出现在 CDMTEST.exe 中。

其他信息: 格式太旧或是类型库无效。

我查了坛子上的其他帖子,也没见到类似的问题。
MSDN中,关于这个问题的示例中,有一个将结构数组作为参数的例子“平台调用数据类型 OutArrayOfStructs 示例”,但它是假设被调用者已经分配了内存,
而我的DLL是要求由调用者来分配内存,而且约定lppList最多不会超出8个。
折腾了一晚上了,也没找到问题在哪??请各位高手帮忙看看,呵呵。
...全文
340 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
关注 帮你顶
dy2712 2006-07-29
  • 打赏
  • 举报
回复
调用的时候不会出现异常了,但是取回来的数据不对,
还有,lpplist++,这样不行吗?那怎么样才能操作IntPtr?
dy2712 2006-07-29
  • 打赏
  • 举报
回复
好的,我试试
mmqingfeng 2006-07-29
  • 打赏
  • 举报
回复
char改bype是需要改的,另外lppList要用IntPtr,预先给他分配好内存
lppList = Marshal.AllocCoTaskMem(sizeof(IntPtr)*8);
之后再调非托管函数,调完之后可以再从lppList中读返回值,读的时候可以用Copy()一次取出来,不用循环,最后再把lppList释放掉,注意放到finally里

手边没环境,只能大概说说,楼主还是自己多试试吧^-^

dy2712 2006-07-29
  • 打赏
  • 举报
回复
把char 改成byte也试过的,还是不行啊。。
我最初是想着用指针来的,但是编译的时候总是报错,无法获取托管类型的地址。不知道是不是我用的不对,呵呵。
Knight94 2006-07-29
  • 打赏
  • 举报
回复
既然你在unsafe块中操作,直接用指针不是更简单些。
Knight94 2006-07-29
  • 打赏
  • 举报
回复
把char改为byte看看
CmUpDate 2006-07-29
  • 打赏
  • 举报
回复
我说错了,少打了一个字,不好意思

-----------------------------------------------------------------------
哎呀,结构和指针还真 没 传过

关注
wufato 2006-07-29
  • 打赏
  • 举报
回复
没用过,帮顶,关注
aSalt 2006-07-29
  • 打赏
  • 举报
回复
mark
CmUpDate 2006-07-29
  • 打赏
  • 举报
回复
哎呀,结构和指针还真传过

关注
dy2712 2006-07-29
  • 打赏
  • 举报
回复
呵呵,刚刚搞错了,调用的时候还是异常,未引用的实例

110,534

社区成员

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

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

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