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个。
折腾了一晚上了,也没找到问题在哪??请各位高手帮忙看看,呵呵。

解决方案 »

  1.   

    既然你在unsafe块中操作,直接用指针不是更简单些。
      

  2.   

    把char 改成byte也试过的,还是不行啊。。
    我最初是想着用指针来的,但是编译的时候总是报错,无法获取托管类型的地址。不知道是不是我用的不对,呵呵。
      

  3.   

    char改bype是需要改的,另外lppList要用IntPtr,预先给他分配好内存
    lppList = Marshal.AllocCoTaskMem(sizeof(IntPtr)*8);
    之后再调非托管函数,调完之后可以再从lppList中读返回值,读的时候可以用Copy()一次取出来,不用循环,最后再把lppList释放掉,注意放到finally里手边没环境,只能大概说说,楼主还是自己多试试吧^-^
      

  4.   

    调用的时候不会出现异常了,但是取回来的数据不对,
    还有,lpplist++,这样不行吗?那怎么样才能操作IntPtr?