我用DELPHI掉用VC写的DLL,调试下来在释放DLL时出错:access violation at 0x0040427e:read of address 0x01240234.
请教高手解决啊!

解决方案 »

  1.   

    DELPHI代码:
    procedure TForm1.Button1Click(Sender: TObject);
    type
      TArr=array[0..4] of string;
      PTArr=^Tarr;
      TCalcProc=function(D_its:integer;p:char;arr:TArr):PTArr;stdcall;
    Var
      c:TArr;
      p:PTArr;
      Calc_ITS:TCalcProc;
      D_its:integer;
      sort:char;
      Hand:THandle;
    begin
      p:=nil;
      Hand:=LoadLibrary('HNT.dll');
      if Hand>0 then begin
        @Calc_ITS:=GetProcAddress(Hand,PChar('Calc'));
        if @Calc_ITS<>nil then
          begin
            c[0]:=Edit1.Text;
            c[1]:=Edit2.Text;
            c[2]:=Edit3.Text;
            c[3]:=Edit3.Text;
            c[4]:=Edit3.Text;        if (Combobox1.text='C10') then D_its:=10;
            if (Combobox1.text='C15') then D_its:=15;
            if (Combobox1.text='C20') then D_its:=20;
            if (Combobox1.text='C25') then D_its:=25;
            if (Combobox1.text='C30') then D_its:=30;
            if (Combobox1.text='C40') then D_its:=40;
            if (Combobox1.text='C50') then D_its:=50;        if (ComboBox2.Text='150X150X150') then sort:='A';
            if (ComboBox2.Text='200X200X200') then sort:='B';
            if (ComboBox2.Text='100X100X100') then sort:='C';        p:=Calc_ITS(D_its,sort,c);        Edit4.text:=p^[0];
            Edit5.text:=p^[1];
            Edit6.text:=p^[2];
            Edit7.text:=p^[3];
            Edit8.text:=p^[4];
          end
        else
         ShowMessage('DLL函数没找到')
      end else
      ShowMessage('DLL调用失败'); FreeLibrary(Hand);end;
    DLL代码:
    #include <afx.h>
    //#include <stdlib.h>double xs,area,rest,a_temp[4],a1;
    CString str;void SelConst(char p)//确定试块的规格和受压面积
    {
    switch(p){
    case 'A': {xs=1.00;area=22500;}break;
    case 'B': {xs=1.05;area=40000;}break;
        case 'C': {xs=0.95;area=10000;}break;
    }
    }double Xyue(double num, int i)//NUM是被修约数,i是保留小数位个数
    {
    double rest,e;//rest是按i的个数扩大e倍所留的余数
        
    switch (i)
    {
    case 1: e=10.0;break;
    case 2: e=100.0;break;
    case 3: e=1000.0;break;
    case 4: e=10000.0;break;
    } rest=(double)((num*e)-(int)(num*e));    if (rest>0.5) num=((int)((num*e)+1))/e;
    if (rest<0.5) num=((int)(num*e))/e;
    if (rest==0.5) 
    {
    if (((int)(num*e))/2==0) num=((int)(num*e))/e;
    else num=((int)(num*e+1))/e;
    } return num;
    }
    extern "C" _declspec(dllexport) CString *Calc(int D_ITS,char sort, CString a[4])
    {
    SelConst(sort);    a_temp[0]=(double)atof(a[0])*xs*1000/area;
        a_temp[1]=(double)atof(a[1])*xs*1000/area;
        a_temp[2]=(double)atof(a[2])*xs*1000/area;
    a_temp[3]=(double)((a_temp[0]+a_temp[1]+a_temp[2])/3);
       
    a[0].Format("%.1f",a_temp[0]);
        a[1].Format("%.1f",a_temp[1]);
    a[2].Format("%.1f",a_temp[2]);
    a[3].Format("%.1f",a_temp[3]);
    if (a_temp[3]>=D_ITS) a[4]="合格";
    else a[4]="不合格";
        
    return a;
    }
      

  2.   

    Hand:=LoadLibrary('HNT.dll');
     FreeLibrary(Hand);
    那是不是在最后一句出错阿~~
    但是就是不知道HNT.dll本身是否有问题~~~
      

  3.   

    0x0040427e编译时生成.map文件,根据这个地址去定位源代码。!!!
      

  4.   

    最后的释放DLL出错,调试时说对无效的指针进行了操作 哪个指针无效了啊?P还是hand?
      

  5.   

    就是在freeLibrary(hand)出错 再跟踪就到CPU汇编代码了 看不动懂老。。
      

  6.   

    这种错误往往是在内存越界后释放的时候产生的问题.
    CString是MFC的类,你返回给Delphi这个类指针,不知道Delphi是不是能很好的处理,建议你返回char**这种基础的类型.
    还有extern "C" _declspec(dllexport) CString *Calc(int D_ITS,char sort, CString a[4])
    CString a[4] 那应该是a[0]-a[3],但是你函数里面出现了a[4].看你前面初始化应该是CString a[5]才对的
    还有pascal和c对函数的参数压栈和出栈顺序方向是不一样的,所以你C函数前面最好加PASCAL这个宏(__stdcall).
    你先把这几个改掉再看看呢
      

  7.   

    AV at 0x0040427e:read of address 0x01240234.
    4xxxxx是主程序,1xxxxx是dll,主程序读/执行dll中的东东遇到非法地址了。
    CString返回给delphi是不行的,CString*也不行,char*也不行。简单的解决方法是定义静态变量static char buffer[256],返回它。更理想的办法应该是像windows api的方法:GetWindowName(LPTSTR buffer, DWORD* len)这样的。
      

  8.   

    谢谢大家 小弟还是用Delphi写吧 完了再研究这个。