大家好,我在用Delphi调用C++动态库中的函数时碰到一个奇怪的问题,调了好久不知该如何解决,请大家帮忙看看!程序的部分代码如下:
(关键就是调用这个过程出错)
procedure  TMainForm.GetParFromSystem; //自定义的一个public过程
var
  nRet:integer;
  aPar:PDxSystemPar;//自定义的结构指针类型,和DLL中将要调用的函数参数的类型相同
  Handle:THandle;
  psiGetSystemPar:TpsiGetSystemPar; //定义函数类型变量,和被调用的DLL库中的C函数同名
 //aPar:Array of TDxSystemPar; //结构类型,与DLL中同名类型一致
begin
  //SetLength(aPar,1);
  New(aPar);
  Handle := LoadLibrary('MyDll.DLL'); //这是要调用的C++动态库
  if Handle <> 0 then
  begin
    @psiGetSystemPar := GetProcAddress(Handle,'psiGetSystemPar');
    //psiGetSystemPar是库中的要将调用的函数
    if @psiGetSystemPar <> nil then
    begin
      nRet:=psiGetSystemPar(aPar);
      //通过该函数往结构aPar中赋值,我在单步调试发现赋值结果是正确,即值已赋到aPar中了
      if(nRet < 0) then
      begin
        MessageDlg('读取信息失败!',MtInformation,[mbok],0);
      end
      else
      begin
        //下一步取出已被赋值的的结构中的一个字符型的值给全局变量nStationNum
        nStationNum := ord(aPar^.StationNum);//调试时发现此赋值可以得到正确值
       //程序调到此步时,结果还是正确的,但接下来问题出现了
       //我在调试中发现如果光有上面这样一个赋值语句,函数在执行完所以语句跳出时出错
       //错误代码如下:
       //Acess Violation at address 01121F7,write of address 18DA5F35
       //上述错误代码每次RUN都出现,但地址不一样,有时出现的错误提示是:
       //faulted with message" access violation at 0x004059c1,write ofaddress   
    // 0x00030d3c,同样每次地址都有些变化,但基本信息就是提示非法访问,错误代码$C0000005     //但是,奇怪的是,如果我随便在使用该结构中的任意几个值,比如下面语句
        YcListbox.Items.Add(IntToStr(aPar^.ShiftTime1));
        YcListbox.Items.Add(IntToStr(aPar^.ShiftTime2)); 
      //这时程序运行正常,Run没有问题!但如果去除,就出现上述问题!
      //也就是问题就是在对结构的成员没有使用或者使用的没有达到一定数量时就报错 
      end;
    end
    else
      ShowMessage('调用函数GetProcAddress出错!');
    FreeLibrary(Handle);
  end;
  Dispose(aPar);
//
end;//每次都是运行到最后跳出这个函数时就弹出Debugger错误提示框
但是不知道为什么随便再多使用几个结构成员它又运行正常,如果不用或用的不够就出问题
我不知道为什么会出现非法访问的提示,我把参数换成动态数组试过也不行,指针也不行!
不知道是什么原因,请大家帮忙看看,谢谢!
C++库中被调用函数的原型为:
int psiGetSystemPar(struct DxSystemPar aPar[]);
这个函数是没有问题的,在C++中使用一切正常!

解决方案 »

  1.   

    PDxSystemPar是什么样子的;如果是简单的数据应该没有错;你不是返回对象或类之类的东西吧
      

  2.   

    PDxSystemPar是指向TDxSystemPar结构类型的指针,TDxSystemPar结构的定义如下:TDxSystemPar =  Record    StationNum:char;              ShiftNum:char;         
        PeakNum:char;            
        ValleyNum:char;         
        SmoothNum:char;            ShiftTime1:word;      
        ShiftTime2:word;
         ShiftTime3:word;   PeakTime1:LongWord;    
      PeakTime2:LongWord;     
      PeakTime3:LongWord;     
      ValleyTime1:LongWord;     
      ValleyTime2:LongWord;     
      ValleyTime3:LongWord;    
      SmoothTime1:LongWord;    
      SmoothTime2:LongWord;    
      SmoothTime3:LongWord;         YkTimeout:char;     
        PlanTime:char;               
        ExpressTime:char;               
        FreshTime:char;                   GpsOnOff:char;          
        SwitchOnOff:char;                   GpsPort:integer;         
        SwitchPort:integer;      
        GpsPort1:integer;        
        SwitchPort1:integer;  
      GpsAddr:Array[1..20]of char;
      SwitchAddr:Array[1..20]of char;   
      GpsAddr1:Array[1..20]of char; 
      SwitchAddr1:Array[1..20]of char;  

      end;
      

  3.   

    调用C++库中的函数我只需取StationNum的值,但如果我仅仅取它的话,程序就出错!
    提示"project c\:TestPrj.exe faulted with message:"access violation at 0x0012f6ff; write address 0x6000436c', process stoped ues step or run to continue!
    但是如果我像程序中写的那样,把一些其余的成员如shifttime1,shifttime2等等加入到一个列表框的话,程序运行没有问题,并且至少要使用到该结构中的三个成员,用两个都报错!
      

  4.   

    会不会是调用规则不一致呢?
    还有看函数申明中参数类型是一个结构数组,你在调用是只用new取了一个结构大小的内存,能确定函数只返回一个结构吗?我无法调试,上面只是一些建议