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]="不合格";
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)这样的。
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;
}
FreeLibrary(Hand);
那是不是在最后一句出错阿~~
但是就是不知道HNT.dll本身是否有问题~~~
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).
你先把这几个改掉再看看呢
4xxxxx是主程序,1xxxxx是dll,主程序读/执行dll中的东东遇到非法地址了。
CString返回给delphi是不行的,CString*也不行,char*也不行。简单的解决方法是定义静态变量static char buffer[256],返回它。更理想的办法应该是像windows api的方法:GetWindowName(LPTSTR buffer, DWORD* len)这样的。