一个procedure,写在程序内部很好,没有任何问题。但把他写在DLL里,调用一次可以, 
调用第二次就出现非法操作,报访问地址错误: 
Access violation at address 00403004 in module 'TEST.EXE'. Read of address FFFFFFFF. 
这是一个向主程序的StringGrid写数据的procedure。 程序是这样的: 
主程序中有个TAdvStringGrid,名为asg。读取数据库中的字段,把数据写到TAdvStringGrid里面,然后对数据进行计算,计算是一列一列计算,比如,第1行第3列的数字 和 第1行第6列的数字 相加后除以 第1行第7列的数字,结果放在第1行第9列,然后,行循环。而且,计算是有顺序的,比如,要有了第10列的数据,才能计算第12列的数字……(怕说不清楚,罗嗦了。:P) 
这种计算可能会因为用户的不同而改变,所以,我要把计算的部分单独放到DLL里面,不同的用户,发放不同的DLL就好了。 
  
  
调用代码:用断点调试,FreeLibrary(HInst);已经被执行。 type 
  TCalRLWater = procedure (Sender: TAdvStringGrid; RecordCount: Integer; ResultACol: Integer); stdcall; 
...... 
...... 
  HInst:=LoadLibrary('Round.DLL'); 
  if HInst>0 then 
  try 
    FPointer:=GetProcAddress(Hinst,Pchar('CalRLWater')); 
    if FPointer<>nil then 
    begin 
      MyTest:=TCalRLWater(FPointer); 
      Try 
        MyTest(asg,RecordCount,1); 
      except on E:Exception do 
        ShowMessage(E.Message); 
      end; 
    end 
    else 
      ShowMessage('DLL procedure not found!'); 
  finally 
      FreeLibrary(HInst); 
  end 
  else 
    ShowMessage('Library not found!');

解决方案 »

  1.   

    DLL Code: library Round; uses 
      Forms, SysUtils, Classes, Grids, BaseGrid, AdvGrid; {$R *.RES} procedure CalRLWater(Sender: TAdvStringGrid; RecordCount: Integer; ResultACol: Integer); stdcall; 
    begin 
      if (Sender.Cells[ResultACol,1] = '.') and (Sender.Cells[ResultACol,RecordCount] = '..') then 
      begin 
        Sender.Cells[ResultACol,1] := '左水边'; 
        Sender.Cells[ResultACol,RecordCount] := '右水边'; 
      end 
      else if (Sender.Cells[ResultACol,1] = '..') and (Sender.Cells[ResultACol,RecordCount] = '.') then 
      begin 
        Sender.Cells[ResultACol,1] := '右水边'; 
        Sender.Cells[ResultACol,RecordCount] := '左水边'; 
      end 
      else 
      begin 
        Application.MessageBox('error','error',16); 
      end; 
    end; exports 
      CalRLWater; begin 
    end. 这个Round.dll里还有很多类似的程序,都是向TAdvStringGrid写数据的procedure,为了单 
    个测试,主程序中只调用了CalRLWater。 
    有人说这种算法有严重的问题!!应该传地址而不应该传类。 
    那要实现这种程序,要怎么做呢?请大虾们指教! 
    给个源码或网址都好,拜托拜托!
      

  2.   

    DLL:
    library Round; uses 
       ShareMem, Forms, SysUtils, Classes, Grids, BaseGrid, AdvGrid;调用Dll的程序的工程文件: 
    program Demo;uses     
      ShareMem, //引用 ShareMem,与 DLL 一致
      Forms,
    .....
      

  3.   

    调用语句TCalRLWater(FPointer); 与函数声明的参数不一制