C结构体
struct ICCCommand
{
  unsigned int function; /* Function (see function table ) */
  unsigned int efIdent; /* short EF-Identifier */
  unsigned int dataPointer; /* file- offset / record number */
  unsigned int lc; /* length send data */
  unsigned char * data; /* send datablock */
  unsigned int le; /* max length response */
};
struct ICCResponse
{
  unsigned char sw1; /* Status bytes */
  unsigned char sw2; /* */
  unsigned int ldata; /* length response */
  unsigned char * data; /* respons datablock */
};
struct ICCSecurity
{
  unsigned char macDown; /* signature algorithm */
  unsigned char macUp; /* */
  unsigned char * macKey; /* signature key */  unsigned char encDown; /* encryption algorithm */
  unsigned char encUp; /* */
  unsigned char * encKey; /* encryption key */
};
C动态库int ICCCreateFile (struct ICCCommand * com,
  struct ICCResponse * res,
  struct ICCSecurity * sec,
  int ch,int mode
  )
delphi结构体
  PICCCommand=^ICCCommand1;
  PICCResponse=^ICCResponse1;
  PICCSecurity=^ICCSecurity1;
  ICCResponse1 = packed record
sw1:byte;
sw2:byte;
ldata:LongWord;
data:PChar;
  end;  ICCCommand1 = packed record
func:LongWord;
efident:LongWord;
datapointer:LongWord;
lc:LongWord;
data:PChar;
le:LongWord;
  end ;  ICCSecurity1 = packed record
macdown:byte;
macup:byte;
mackey:pchar;
encdown:byte;
encup:byte;
enckey:pchar;
  end ;
 delphi调用
function ICCCreateFile1(var command:PICCcommand; var response:PICCresponse;var security:PICCSecurity;handle_IC,t:LongInt):LongInt;external 'cardos32.dll' name 'ICCCreateFile';  New(ic_command1);
  New(ic_reutrn1);
  New(ic_security1);
  tryic_command1.func := 63 ;
ic_command1.efIdent := 0 ;
ic_command1.datapointer := 0 ;  s1 := '0000000038ffffff0000';
  ic_command1.data := StrNew(PChar(S1));//ic_command1.data := P2;//'0000000038ffffff0000' ;
ic_command1.lc := 10 ;
ic_command1.le := 300 ;
  s := space(300);
  ic_reutrn1.data := StrNew(PChar(S));
 // StrCopy(ic_reutrn1.data,@s);
// ic_reutrn1.data := space(300) ;
ic_security1.encDown := 0 ;
ic_security1.encUp := 0 ;
ic_security1.macDown := 0 ;
ic_security1.macUp := 0 ;  if ICCCreateFile1(ic_command1,ic_reutrn1,ic_security1,handle_ic,1) = 0 then
这一句一调用就报地址错误,各位帮忙看一下什么原因呢,谢谢

解决方案 »

  1.   

    你把function中ICCCreateFile1(ic_command1,ic_reutrn1,ic_security1,handle_ic,1)的每一個參數show出來看一下結果是多少...
      

  2.   

    to kye_jufei
    因为C写的没有编译环境,在它里面看不到传进去的参数值,在没有调用之前这些个是有赋值的
      

  3.   

    不行,还是一样一运行if ICCCreateFile1(ic_command1,ic_reutrn1,ic_security1,handle_ic,1) = 0 then这句就报错,会不会和结构体数据类型是有关呢,我想也没定义错啊
      

  4.   

    1. 去掉全部的 packed
    2. 函数翻译:一个注意调用约定,按照你给的c声明应该是 cdecl
    要么
    function ICCCreateFile1(var command: ICCcommand; var response: ICCresponse; var security: ICCSecurity;handle_IC,t:LongInt):LongInt; cdecl;
    要么
    function ICCCreateFile1(command: PICCcommand; response: PICCresponse;security: PICCSecurity; handle_IC,t:LongInt):LongInt;external 'cardos32.dll' name 'ICCCreateFile'; cdecl;不要同时用 var 和指针声明,根本对不上
      

  5.   

    to Seamour 
    谢谢你,这个函数已经可以调用了,另外我想问一下
    var
       ls_return:string;
       ic_command1:PICCCommand;
       ic_reutrn1:PICCResponse;
       ic_security1:PICCSecurity;
       s,s1:string;
       p1,p2:PChar;
    begin
      New(ic_command1);
      New(ic_reutrn1);
      New(ic_security1);
      try
        ic_command1.func := 63 ;
        ic_command1.efIdent := 0 ;
        ic_command1.datapointer := 0  ;
        s1 := '0000000038ffffff0000';
        ic_command1.data := StrNew(PChar(S1));
        ic_command1.lc := 10  ;
        ic_command1.le := 300 ;
        s := space(300);
        ic_reutrn1.data := StrNew(PChar(S));
        ic_security1.encDown := 0 ;
        ic_security1.encUp := 0  ;
        ic_security1.macDown := 0 ;
        ic_security1.macUp := 0  ;    if ICCCreateFile1(ic_command1,ic_reutrn1,ic_security1,handle_ic,1) = 0 then
          s:=''
        else
          s:='';
      finally
    //    StrDispose(p1);
    //    StrDispose(p2);
      //  freemem(ic_security1);
      //  freemem(ic_reutrn1);
      //  freemem(ic_command1);
        Dispose(ic_security1);
        Dispose(ic_reutrn1);
        Dispose(ic_command1);
      end;
    在释放的时候报地址错误,是不是用strnew创建的也要先释放,怎么释放呢
      

  6.   

    StrDispose(ic_command1.data)
    你申请了一个值为p1的空间,把地址赋给了ic_command1.data
      

  7.   

    不管是StrDispose(ic_command1.data)
    还是Dispose(ic_security1);
    都可以执行,但是运行到函数最后的时候报错(应该是离到函数体时),
    函数体最后是释放Dispose(ic_security1)
      

  8.   

    很可能你的ICCCreateFile1函数中对指针ic_command1进行了操作,破坏了ic_command1指针,那样在释放就会出错
      

  9.   

    to bdmh 
    对,在dll中是要对ic_reutrn1进行操作的,因为它是一个返回值
      

  10.   

    to bdmh 
    要怎么释放呢,难道释放不了?
      

  11.   

    int  ICCCreateFile (struct ICCCommand * com,
                                            struct ICCResponse * res,
                                            struct ICCSecurity * sec,
                                            int ch,int mode
                                            )
    {
    int           status, line,olen;
    unsigned char data[200];     


    if(mode/2==0)
    memcpy(data,com->data,com->lc);
    else
        AsciiToChar(data,com->data,com->lc);

        if(mode<2)
         {
         InCommand( ch, CLASS, Create_File[CardOSVersion] , com->function*P1POWER,
          (unsigned char)com->lc, data, &(res->sw1), &(res->sw2),
        &status, &line,&olen,4,(unsigned char)com->le);
    }
    else     
         {
         InCommand_echo( ch, CLASS, Create_File[CardOSVersion] , com->function*P1POWER,
          (unsigned char)com->lc, data, &(res->sw1), &(res->sw2),
        &status, &line,&olen,4,(unsigned char)com->le);
    }

    if(line!=0)
    return NOSEND;

    if(status==0)
    {
    res->ldata=(unsigned int)olen;
       if(mode/2==0)
         memcpy(res->data,data,olen);    在此处修改了
           else
           CharToAscii(res->data,data,olen);
         }
        else
         res->ldata=0;
        
    return status;

    这是C这个函数的完整实现
      

  12.   

    结构体
    ICCResponse1 = packed record
    sw1:byte;
    sw2:byte;
    ldata:integer;
    data:PChar;
      end;ldata:integer;
    试试。function ICCCreateFile1(var command:PICCcommand; var response:PICCresponse;var security:PICCSecurity;handle_IC,t:LongInt):LongInt;external 'cardos32.dll' name 'ICCCreateFile';
    加上 stdcall 试试
      

  13.   

    to mjp1234airen4385 
    这种方法不行,最开始就是这样,按Seamour 7楼的方法可以调用了
    用你的方法调用报地址错误
      

  14.   

    to bdmh有什么办法解决吗?因为这个C库是改不了的,是别人写好的,很多应用在用,只能去迁就它
      

  15.   

    你这里根本就用不着动态申请内存,直接都用局部变量就够了,少操作点儿内存也能减少出错的可能。用 var x: tt 声明的话直接传就可以了(所以我把更方便的声明方式写在前面);x: Ptt 的话,还得取地址再传,稍微麻烦一些。
    懒得看你贴的代码了,八成是某个要传 char * 需要写,你不但没给分配内存,还传了个野指针
      

  16.   

    现在不报错了,问题出在
    s1 := '0000000038ffffff0000';
    ic_command1.data := StrNew(PChar(S1));
    改成
    s1 := '0000000038ffffff0000';
    edit.Text := s1;
    edit.GetTextBuf(strdata,1024);
    ic_command1.data := strdata;//StrNew(PChar(S1));
    但是gettextbuf要带个编辑控件吗?有没有等价的,是不是getmem呢?