注意:兄弟们没多少分了海涵....................CxybClient.dll 为c++ 开发的动态链接库不管怎样也不能正常调用,运行软件很快就报错"Access violation at address 10001832 in module 'CxybClient.dll' . Read of address 00000000." 好像根本就没检测CxybClient.dll里面的东西。如果调用正常的话应该很长时间没反映(VB在初始化正常的情况下调用正常)
///正文如下。unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;Type str_out=record
    errtext :Pchar;
    out1 :Pchar;
    out2 :Pchar;
    out3 :Pchar;
    out4 :Pchar;
    out5 :Pchar;
    out6 :Pchar;
    out7 :Pchar;
    out8 :Pchar;
    out9 :Pchar;
    out10 :Pchar;
    out11 :Pchar;
    out12 :Pchar;
    out13 :Pchar;
    out14 :Pchar;
    out15 :Pchar;
    out16 :Pchar;
    out17 :Pchar;
    out18 :Pchar;
    out19 :Pchar;
    out20 :Pchar;
    out21 :Pchar;
    out22 :Pchar;
    out23 :Pchar;
    out24 :Pchar;
    out25 :Pchar;
    out26 :Pchar;
    out27 :Pchar;
    out28 :Pchar;
    out29 :Pchar;
    out30 :Pchar;
End;var
  Form1: TForm1;implementation{$R *.dfm}
FUNCTION readzfbl(ybjgbm:Pchar;yybm:Pchar;yycxbm:Pchar;strbz:Pchar;strout:str_out):Boolean; cdecl; external 'CxybClient.dll';procedure TForm1.Button1Click(Sender: TObject);
var
  par_out:str_out;
begin
  GetMem(par_out.errtext,1024);   GetMem(par_out.out1,50); GetMem(par_out.out2,50); GetMem(par_out.out3,50); GetMem(par_out.out4,50); GetMem(par_out.out5,50);
  GetMem(par_out.out6,50);      GetMem(par_out.out7,50); GetMem(par_out.out8,50); GetMem(par_out.out9,50); GetMem(par_out.out10,50); GetMem(par_out.out11,50);
  GetMem(par_out.out12,50);     GetMem(par_out.out13,50); GetMem(par_out.out14,50); GetMem(par_out.out15,50); GetMem(par_out.out16,50); GetMem(par_out.out17,50);
  GetMem(par_out.out18,50);     GetMem(par_out.out19,50); GetMem(par_out.out20,50); GetMem(par_out.out21,50); GetMem(par_out.out22,50); GetMem(par_out.out23,50);
  GetMem(par_out.out24,50);     GetMem(par_out.out25,50); GetMem(par_out.out26,50); GetMem(par_out.out27,50); GetMem(par_out.out28,50); GetMem(par_out.out29,50);
  GetMem(par_out.out30,50);  If readzfbl('asdf','wer','werf','dweer',par_out) then
  begin
  end;  Freemem(par_out.errtext);   Freemem(par_out.out1); Freemem(par_out.out2); Freemem(par_out.out3); Freemem(par_out.out4); Freemem(par_out.out5);
  Freemem(par_out.out6);      Freemem(par_out.out7); Freemem(par_out.out8); Freemem(par_out.out9); Freemem(par_out.out10); Freemem(par_out.out11);
  Freemem(par_out.out12);     Freemem(par_out.out13); Freemem(par_out.out14); Freemem(par_out.out15); Freemem(par_out.out16); Freemem(par_out.out17);
  Freemem(par_out.out18);     Freemem(par_out.out19); Freemem(par_out.out20); Freemem(par_out.out21); Freemem(par_out.out22); Freemem(par_out.out23);
  Freemem(par_out.out24);     Freemem(par_out.out25); Freemem(par_out.out26); Freemem(par_out.out27); Freemem(par_out.out28); Freemem(par_out.out29);
  Freemem(par_out.out30);end;end.

解决方案 »

  1.   

    par_out 是传出的参数要初始化!
      

  2.   

    在windows下好象是stdcall格式传参数,你那个cdecl好象不对吧
      

  3.   

    又没有CxybClient.dll的函数及对应参数说明vb是怎么调用的?'00000000'的错误是没有对象你调用函数顺序对嘛?
    要先调用初始化的函数?
      

  4.   

    VB 调用
    Public Type str_out
      errtext As String
      out1 As String
      out2 As String
      ..............
      out30 As String
    End TypePublic Type str_in
      ybjgbm As String
      yybm As String
      int1 As String
      .............. 
      int10 As String
    End TypeSub init_type(par_in As str_in, par_out As str_out)With par_in
      .ybjgbm = "430700"
      .yybm = "4307000001"
      ...............
    End With
      par_out.errtext = Space(1024)
      par_out.out1 = Space(50)
      par_out.out2 = Space(50)
      .....................
    End SubPrivate Sub Command1_Click()
    Dim bln_return As Boolean
    Dim par_in As str_in
    Dim par_out As str_out
    init_type par_in, par_outPublic Declare Function readzfbl Lib "cxybclient.dll" ( _
    ByVal strybjgbm As String, ByVal stryybm As String _
    , ByVal stryycxbm As String, ByVal strbz As String _
    , strout As str_out) As Boolean最上面是delphi 调用,没有初始化函数
      

  5.   

    把你的动态库C函数原型贴出来,你确定动态库里面函数输出是以cdecl出来的?这关系到参数入栈循序及清除栈的归属问题。
      

  6.   

    这个是orcle 下面的函数与此函数类似prompt Creating function CYJS
    prompt ======================
    prompt
    create or replace function cyjs(ls_instr in varchar2) return varchar2 is
      Result varchar2(1024);
      ls_str varchar2(1024);
      ll_pos  int;
      ls_aab034  varchar2(18);
      ls_akb020  varchar2(20);
      ls_zyh  varchar2(18);
      ll_count   number;
      ls_akc190 varchar2(18);
      ls_akc189 varchar2(18);
      ls_errtext  varchar2(100);
      ls_cysj     varchar2(20);
      ls_czy      varchar2(20);
      ls_dewbz    varchar2(1);
      ls_akc328   varchar2(1);
      ls_alc020   varchar2(8);
      ls_aac001   varchar2(20);
      ls_aae116   varchar2(3); --工伤待遇状态
      ld_ALC026   date;        --工伤申请认定时间
      ls_ALA040   varchar2(3); --工伤等级
      ls_aac031   varchar2(1);--人员参保状态
      ld_bac132   date;
      ls_ret      varchar2(100);
      ln_akc264   number(12,2);
      ln_akc263   number(12,2);
      ln_akc265   number(12,2);
      ls_aab001   varchar2(20);
      ls_aab004   varchar2(100);
      ls_aac002   varchar2(18);
      ls_aac003   varchar2(20);
      ls_AKC231   varchar2(100);
      ld_akc194   date;
      ld_AKC192   date;
      ld_sysdate  date;
      ls_AKC325   varchar2(1);
      ls_akc300   varchar2(3);
      ls_akc500   varchar2(3);
      ls_akb021   varchar2(50);
      ls_alc042   varchar2(3);
      ls_akc126   varchar2(1);
      ls_akc330   varchar2(4000);
      le         EXCEPTION;
    begin
     -- select
      ls_errtext := '';
      --ls_str :=ls_instr;  ll_pos := instr(ls_instr,',',1,1);
      ls_dewbz := rtrim(ltrim(substr(ls_instr,1,ll_pos - 1)));
      ls_str := substr(ls_instr,ll_pos + 1,length(ls_instr) - ll_pos);  ll_pos := instr(ls_str,',',1,1);
    --  ls_str := substr(ls_str,ll_pos + 1,length(ls_str) - ll_pos);
      ls_aab034:=rtrim(ltrim(substr(ls_str,1,ll_pos - 1)));  --工伤机构编码
      ls_str := substr(ls_str,ll_pos + 1,length(ls_str) - ll_pos);  ll_pos := instr(ls_str,',',1,1);
      ls_akb020:=rtrim(ltrim(substr(ls_str,1,ll_pos - 1)));  --协议机构编码
      ls_str := substr(ls_str,ll_pos + 1,length(ls_str) - ll_pos);  ll_pos := instr(ls_str,',',1,1);
      ls_zyh := rtrim(ltrim(substr(ls_str,1,ll_pos - 1)));  --住院号
      ls_str := substr(ls_str,ll_pos + 1,length(ls_str) - ll_pos);  ll_pos := instr(ls_str,',',1,1);
      ls_cysj:= rtrim(ltrim(substr(ls_str,1,ll_pos - 1)));
      ls_str := substr(ls_str,ll_pos + 1,length(ls_str) - ll_pos); --出院时间 -- ll_pos := instr(ls_str,',',1,1);
     -- ls_str := substr(ls_str,ll_pos + 1,length(ls_str) - ll_pos); --操作员
      ls_czy:= rtrim(ltrim(ls_str));  if ls_zyh is null then
         ls_errtext:='住院号不能为空';
         raise le;
      end if;
      if ls_akb020 is null then
         ls_errtext:='协议机构编码不能为空';
         raise le;
      else
          select akb021 into ls_akb021 from v_lb30andlb31andlb32@ybyy where akb020=ls_akb020;
          if sqlcode < 0 then
            raise le;
          end if;  end if;
      if ls_cysj is null then
         ls_errtext:='出院时间不能为空';
         raise le;
      else
          select to_date(ls_cysj,'yyyy-mm-dd hh24:mi:ss'),sysdate into ld_akc194,ld_sysdate from dual;
          if sqlcode <> 0 then
              ls_errtext:='转换出院时间错误!';
             raise le;
          end if ;
      end if;
      select akc190,akc328,alc020,aac001,AKC231,akc192,AKC325,akc300,akc500,akc126
      into ls_akc190,ls_akc328,ls_alc020,ls_aac001,ls_AKC231,ld_AKC192,ls_AKC325,ls_akc300,ls_akc500,ls_akc126
      from lc35@ybyy
      where akb020=ls_akb020 and aab034=ls_aab034 and akc191=ls_zyh;
      if sqlcode <> 0 then
         ls_errtext:='该工伤人员没有办理入院申报或是存在多次入院申报 信息';
         raise le;
      else
         if ls_akc328 is null or ls_akc328='0' then
            ls_errtext:='该工伤人员的住院申报没有审批,不能办理出院结算';
            raise le;
         end if;
         if ls_akc126 = '1' then
            ls_errtext:='该工伤人员的已经办理出院,不能办理出院结算';
            raise le;
         end if;
         select aae116,ALC026,ALA040,alc042
          into ls_aae116,ld_ALC026,ls_ALA040 ,ls_alc042
          from lc01@ybyy where aac001 = ls_aac001 and alc020=ls_alc020;
         if sqlcode <> 0 then
            ls_errtext:='取该人员工伤待遇状态错误!';
            raise le;
         end if;
         if ls_aae116<>'1' and ls_aae116<>'2' then
            ls_errtext:='该人员没有完成工伤申报、认定信息的申报,不能办理出院!';
            raise le;
         end if;     select aab001,aac031,bac132,aac002,aac003
         into ls_aab001,ls_aac031, ld_bac132,ls_aac002,ls_aac003
          from ac01@ybyy where aac001=ls_aac001;
         if sqlcode <> 0 then
            ls_errtext:='取该人员参保状态错误';
            raise le;
     --    else
      --       if ls_aac031='2' or ls_aac031='3' then
      --          if ls_ala040 = '00' or ls_ala040 = '05' or ls_ala040 = '06' or ls_ala040 = '07' or ls_ala040 = '08' or ls_ala040 = '09' or ls_ala040='10' then
     --              ls_errtext:='该人员停保,且不是1-4级伤残等级,不能再报销医疗费!';
      --             raise le;
      --          end if;
       --      end if;
         else
             select aab004 into ls_aab004 from ab01@ybyy where aab001=ls_aab001;
             if sqlcode <> 0 then
                ls_errtext:='取单位名称错误';
                raise le;
             end if;
         end if;
      end if;
    ls_ret := cxcyjs.uf_update_lc40(ls_aab034 ,ls_akb020,ls_zyh,ls_akc190,ls_aac001,ls_alc020,ld_ALC026 );
    if ls_ret <> '' then
       Result:='1,'||ls_ret;
    else
       select nvl(sum(akc253),0),nvl(sum(akc227),0) into ln_AKC265,ln_AKC263
       from lc40@ybyy where aab034=ls_aab034 and akc190=ls_akc190 and akb020=ls_akb020;
       if sqlcode <> 0 then
          ls_errtext:='取该人员总费用失败!';
          raise le;
       end if;
    end if;
    ls_akc330:= cxcyjs.uf_get_akc330(ls_aab034,ls_akb020,ls_zyh,ls_akc190);
    if length(ls_akc330)>4000 then
       ls_akc330:=substr(ls_akc330,1,4000);
    end if;
    insert into lc39@ybyy  ( AKC190, AKB020,  BLC001, AAB001, AAB004, AAC001 ,
                         AAC002, AAC003 , AKC230, AKC231, AKC192, AKC194,
                         AKC325, AKC195 , AKC264, AKC263, AKC265, AKC266,
                         AKC267, AKC268 , AKC269, AKC270, AKC271,AKC272,
                         AKC273, AKC274 , AKC275 ,AKC276,AKC277, AKC278 ,
                         AKC279 ,AKC280,  AKC300, AKC281, AKC282, AKC283 ,
                         AKC284, AKC285,  AKC286, AKC287, AKC288 ,AKC301 ,
                         AKC330, AKC331,  AKC332, AKC333 ,AKC334 , AKC336 ,
                         AKC337 , AKC191 ,AKC338 ,AAB034 , AKC339 , ALC042 ,
                          AKC500 )
       values (ls_akc190,ls_akb020,ls_alc020,ls_aab001,ls_aab004,ls_aac001,
              ls_aac002,ls_aac003,'',ls_AKC231,ld_akc192,to_date(ls_cysj,'yyyy-mm-dd hh24:mi:ss'),
              ls_AKC325,ld_sysdate,ln_AKC265+ln_AKC263, decode(ls_akc300,'0',ln_AKC263,'9',ln_AKC263,0),decode(ls_akc300,'0',ln_AKC265,'9',ln_AKC265,0),0
              ,0,0,0,0,0,0,
              0,0,0,0,0,decode(ls_akc300,'2',ln_AKC263,0),
              decode(ls_akc300,'2',ln_AKC265,0),'1',ls_akc300,0,0,0,
              0,0,0,0,0,'0',
              ls_akc330,0,decode(ls_akc500,'0','0','1'),ls_czy,ld_sysdate,ls_akb021,
              '',ls_zyh,'',ls_aab034,decode(sign((ln_AKC265+ln_AKC263) - 50000),-1,'1','0'),ls_alc042,
              ls_akc500);
     if sqlcode <> 0 then
        ls_errtext:='生成结算lc39失败';
        raise le;
     end if; insert into lc41@ybyy ( AKC190,AKB020,AKA063,AKC253 ,
    AKC227 ,AKC192,AKC194, AKC195,
    AKC191,aab034)
    select ls_akc190,ls_akb020,AKA063,nvl(sum(akc253),0),
      nvl(sum(akc227),0), ld_akc192,to_date(ls_cysj,'yyyy-mm-dd hh24:mi:ss'),ld_sysdate,
      akc191,aab034
    from lc40@ybyy
    where akc190 = ls_akc190 and akb020 = ls_akb020 and aab034 = ls_aab034  group by aka063,akc191,aab034;
      if sqlcode <> 0 then
        ls_errtext:='生成结算分类信息lc40失败';
        raise le;
      end if;
      update lc35@ybyy set AKC126 = '1',akc194=to_date(ls_cysj,'yyyy-mm-dd hh24:mi:ss')
       where akc190 = ls_akc190 and akb020 = ls_akb020 and aab034 = ls_aab034 ;
      if sqlcode <> 0 then
         ls_errtext:='更新LC35结算标志错误失败!';
         raise le;
      end if;
      if ls_akc500='0' then   --单位欠费
        if ls_akc330 is null then
           Result:='0,'||(ln_AKC265+ln_AKC263)||','||(ln_AKC265+ln_AKC263)||','||0||','||' ';
        else
    --       Result:='0,'||(ln_AKC265+ln_AKC263)||','||(ln_AKC265+ln_AKC263)||','||0||','||ls_akc330;
           Result:='0,'||(ln_AKC265+ln_AKC263)||','||(ln_AKC265+ln_AKC263)||','||0||' ';
        end if;
      else
    --    if ls_akc330 is null then
            Result:='0,'||(ln_AKC265+ln_AKC263)||','||ln_AKC265||','||ln_AKC263||','||' ';
    --    else
    --        Result:='0,'||(ln_AKC265+ln_AKC263)||','||ln_AKC265||','||ln_AKC263||','||ls_akc330;
     --   end if;
      end if;
     commit;
    return(Result);
    EXCEPTION
    WHEN le THEN
         BEGIN
           rollback;
           Result:='1,'||ls_errtext||upper(sqlerrm);
           return(Result);
         END;
      WHEN OTHERS THEN
         BEGIN
           rollback;
           Result:='1,'||ls_errtext||upper(sqlerrm);
           return(Result);
         END;
    end cyjs;
      

  7.   

    你这个dll用其他的语言能够调用正常么?
    一般这个错跟对象、内存有关、你看看你对象、再看看整理内存了没、
      

  8.   

    友情提醒,CSDN不允许倒分,否则将被封号
    请LZ谨慎发帖,认真结帖