问题解决倾分相送
体情况说明
1.delphi中声明如下
function getdata(l_cominfoU1a,l_cominfoU1b,l_cominfoU2a,l_cominfoU2b,l_cominfoU3a,l_cominfoU3b,l_cominfoU4:Longint;strdata,errmessage:pchar):Longint stdcall;external 'KCM.dll';
//前7参数为usb端口号句柄,后面参数“strdata:是要传给dll的处理的原始数据串,errmessage是截获的错误信息;函数返回值是整型2.vc 写的dll (用vb调用通过不会报任何错误)
vc 代码 程序如下:
extern "C" unsigned short pascal getdata(HANDLE fd1,HANDLE fd2,HANDLE fd3,HANDLE fd4,HANDLE fd5,HANDLE fd6,HANDLE fd7,unsigned char *Data,unsigned char *message)
{
unsigned short ret;
/************************************************************************************/ //fd1复位
if ((ret=icc_reset(fd1)!=0x9000)//函数icc_reset探测有没有端口有没有插入usb设备的函数有则返回0x9000,无则报其他错误(如ox6805)
{strcpy((char *)message,"USB 1: 复位"); strcat((char *)message,"\x0"); return ret;} //fd2复位
if ((ret=icc_reset(fd2)!=0x9000)
{strcpy((char *)message,"USB 2: 复位"); strcat((char *)message,"\x0"); return ret;} //fd3复位
if ((ret=icc_reset(fd3)!=0x9000)
{strcpy((char *)message,"USB 3: 复位"); strcat((char *)message,"\x0"); return ret;}
//fd4复位
if ((ret=icc_reset(fd4)!=0x9000)
{strcpy((char *)message,"USB 4: 复位"); strcat((char *)message,"\x0"); return ret;}
//fd5复位
if ((ret=icc_reset(fd5)!=0x9000)
{strcpy((char *)message,"USB 5: 复位"); strcat((char *)message,"\x0"); return ret;}
//fd6复位
if ((ret=icc_reset(fd6)!=0x9000)
{strcpy((char *)message,"USB 6: 复位"); strcat((char *)message,"\x0"); return ret;}
//fd7复位
if ((ret=icc_reset(fd7)!=0x9000)
{strcpy((char *)message,"USB 7: 复位"); strcat((char *)message,"\x0"); return ret;}
{处理跟usb数据通信的部分}
return ret;
}用delphi调用能获得返回值0x9000 但是再运行下去就报无效指针错误或内存错误。dll应该没问题用vb程序调用测试通过,一且正常。
因为是vc写得所以dll也无法加sharemem。
请各位大虾指点,小弟不才 数全给了以报答谢之恩。
体情况说明
1.delphi中声明如下
function getdata(l_cominfoU1a,l_cominfoU1b,l_cominfoU2a,l_cominfoU2b,l_cominfoU3a,l_cominfoU3b,l_cominfoU4:Longint;strdata,errmessage:pchar):Longint stdcall;external 'KCM.dll';
//前7参数为usb端口号句柄,后面参数“strdata:是要传给dll的处理的原始数据串,errmessage是截获的错误信息;函数返回值是整型2.vc 写的dll (用vb调用通过不会报任何错误)
vc 代码 程序如下:
extern "C" unsigned short pascal getdata(HANDLE fd1,HANDLE fd2,HANDLE fd3,HANDLE fd4,HANDLE fd5,HANDLE fd6,HANDLE fd7,unsigned char *Data,unsigned char *message)
{
unsigned short ret;
/************************************************************************************/ //fd1复位
if ((ret=icc_reset(fd1)!=0x9000)//函数icc_reset探测有没有端口有没有插入usb设备的函数有则返回0x9000,无则报其他错误(如ox6805)
{strcpy((char *)message,"USB 1: 复位"); strcat((char *)message,"\x0"); return ret;} //fd2复位
if ((ret=icc_reset(fd2)!=0x9000)
{strcpy((char *)message,"USB 2: 复位"); strcat((char *)message,"\x0"); return ret;} //fd3复位
if ((ret=icc_reset(fd3)!=0x9000)
{strcpy((char *)message,"USB 3: 复位"); strcat((char *)message,"\x0"); return ret;}
//fd4复位
if ((ret=icc_reset(fd4)!=0x9000)
{strcpy((char *)message,"USB 4: 复位"); strcat((char *)message,"\x0"); return ret;}
//fd5复位
if ((ret=icc_reset(fd5)!=0x9000)
{strcpy((char *)message,"USB 5: 复位"); strcat((char *)message,"\x0"); return ret;}
//fd6复位
if ((ret=icc_reset(fd6)!=0x9000)
{strcpy((char *)message,"USB 6: 复位"); strcat((char *)message,"\x0"); return ret;}
//fd7复位
if ((ret=icc_reset(fd7)!=0x9000)
{strcpy((char *)message,"USB 7: 复位"); strcat((char *)message,"\x0"); return ret;}
{处理跟usb数据通信的部分}
return ret;
}用delphi调用能获得返回值0x9000 但是再运行下去就报无效指针错误或内存错误。dll应该没问题用vb程序调用测试通过,一且正常。
因为是vc写得所以dll也无法加sharemem。
请各位大虾指点,小弟不才 数全给了以报答谢之恩。
解决方案 »
- dxDBGrid 输入数据
- 怎么在Panel 上画图!
- 简单问题:Fast Report3 中如何把合计功能显示在报表(多页)的最后一条记录下面,答对就给分!!!
- 如何改变整个系统中文字的字体?
- 向数据库添加记录成功但delphi7会报错,怎么回事啊
- SQL SERVER对IP的依赖问题
- 我想在运行一个表单时, 鼠标变成漏斗形的,要怎么做?
- DELPHI中时间与SQLSERVER7中的时间兼容问题
- 那里有DCOM FOR 98下载?
- delphi 10 移动开发如何保存密码和读取保存的密码?
- 在delphi中 如何实现 USB摄像头捕获视频显示?
- cxgrid的gridmode=true时,如何实现排序?
2.楼书说的"但是再运行下去就报无效指针错误或内存错误。"是什么意思? 调用DLL函数的语句正确,但下一步就错误了? 不明白你说的是什么情况下出的错.你可以把调用的部分拿出来,然后说运行到哪一步时出什么错了.
function getdata() stdcall;vc 代码 程序如下:
extern "C" unsigned short pascal getdata()兄弟,stdcall与pascal 不协调,二者对参数的压栈顺序不一样:
stdcall 按从右至左的顺序压参数入栈
pascal 按从左至右的顺序压参数入栈 ...其它的与_stdcall相同;
function getdata(l_cominfoU1a,l_cominfoU1b,l_cominfoU2a,l_cominfoU2b,l_cominfoU3a,l_cominfoU3b,l_cominfoU4:Longint;strdata,errmessage:pchar):Longint pascal;external 'KCM.dll'; 把stdcall 改为 pascal 就可以了
返回值是调试跟踪观察的。
后面函数如下 if ierr=$9000 then
begin
SB.Panels[0].Text:='检查完毕!';
showmessage('OK') ;
try ct_close(l_cominfoUSB1);
ct_close(l_cominfoUSB2);
ct_close(l_cominfoUSB3);
ct_close(l_cominfoUSB4); except
end;
end
else
begin
SB.Panels[0].Text:='发行失败!';
try
ct_close(l_cominfoUSB1);
ct_close(l_cominfoUSB2);
ct_close(l_cominfoUSB3);
ct_close(l_cominfoUSB4);
except
end;
end;
调试发现只要对窗体或某个控件赋值或显示举报错,或程序推出!
如:
SB.Panels[0].Text:='检查完毕!';
或
showmessage('OK') ;
就报错。
把这两行都去掉,则是报错的地方是 跟踪完成 再显示窗体的时候错误。窗体hook什么的报错。
errmessage:array[0..1023] of char
或者 GetMem(ErrMessage,1023);
然後再調用函數
并且都获得了值再传给要调用getdata函数的,谢谢你。
或
showmessage('OK') ; 而用pascal 调试获得不了值,并且函数还没跳出来就报错了。
谢谢两位了。
回复:
大虾们,我跟踪调试发现用stdcall能得到返回值ox9000,只是后面总报错。比如 SB(Statebar).Panels[0].Text:='检查完毕!';
或
showmessage('OK') ; 而用pascal 调试获得不了值,并且函数还没跳出来就报错了。
谢谢两位了
刚才试了,不行能获得返回值,但是还是老问题,运行到SB.Panels[0].Text:='检查完毕!';就报错。谢谢你!
var
strTMP :string;
ierr :Integer;
errmessage,strdata:PChar;
begin button1.Enabled:=false;
strdata:=PChar(Edit1.Text);
if strdata='' then
begin
Application.MessageBox(PChar('传递数据不能为空!'),'信息提示',MB_OK+MB_ICONERROR);
Exit;
end else
begin
strtmp:='';
strtmp:= CheckUSB ;//返回值为string 检查是否都有插入usb设备,如果都有则返回空,否则返回具体信息
//通过这个函数获得usb的各个端口句柄值(本窗体公共变量),供传给getdata函数用
if strtmp<>'' then
begin
Application.MessageBox(PChar(strtmp),'信息提示',MB_OK+MB_ICONERROR);
Exit;
end else //调用动态库函数
begin
try
flag:='0101010';
ierr:=$9000;
// GetMem(ErrMessage,1023);
SB.Panels[0].Text:='正在通信...';
screen.Cursor:=crHourGlass;
ierr:=Issue(l_cominfoUSB1,l_cominfoUSB1,l_cominfoUSB2,l_cominfoUSB2,l_cominfoUSB3,l_cominfoUSB3,l_cominfoUSB4,strdata,errmessage);
finally
screen.Cursor:=crdefault;
button1.Enabled:=true;
end;
if ierr=$9000 then
begin
try
SB.Panels[0].Text:='检查完毕!'; //程序一般在这报错
showmessage('OK') ; //注释掉上行则本行报错
ct_close(l_cominfoUSB1);//关闭端口
ct_close(l_cominfoUSB2);
ct_close(l_cominfoUSB3);
ct_close(l_cominfoUSB4); except
end;
end
else
begin
SB.Panels[0].Text:='通信失败!';
try
ct_close(l_cominfoUSB1);
ct_close(l_cominfoUSB2);
ct_close(l_cominfoUSB3);
ct_close(l_cominfoUSB4);
except
end;
end;
end;
end;
end;
I补充 issue 函数 就是getdata函数
{
unsigned short ret;
//fd1复位
if ((ret=icc_reset(fd1)!=0x9000)//函数icc_reset探测有没有端口有没有插入usb设备的函数有则返回0x9000,无则报其他错误(如ox6805)
{strcpy((char *)message,"USB 1: 复位"); strcat((char *)message,"\x0"); return ret;} //fd2复位
if ((ret=icc_reset(fd2)!=0x9000)
{strcpy((char *)message,"USB 2: 复位"); strcat((char *)message,"\x0"); return ret;} //fd3复位
if ((ret=icc_reset(fd3)!=0x9000)
{strcpy((char *)message,"USB 3: 复位"); strcat((char *)message,"\x0"); return ret;} //fd4复位
if ((ret=icc_reset(fd4)!=0x9000)
{strcpy((char *)message,"USB 4: 复位"); strcat((char *)message,"\x0"); return ret;} //fd5复位
if ((ret=icc_reset(fd5)!=0x9000)
{strcpy((char *)message,"USB 5: 复位"); strcat((char *)message,"\x0"); return ret;} //fd6复位
if ((ret=icc_reset(fd6)!=0x9000)
{strcpy((char *)message,"USB 6: 复位"); strcat((char *)message,"\x0"); return ret;} //fd7复位
if ((ret=icc_reset(fd7)!=0x9000)
{strcpy((char *)message,"USB 7: 复位"); strcat((char *)message,"\x0"); return ret;} {处理跟usb数据通信的部分} 略去(只保留判断是否有端口设备不处理数据),
return ret;
} --------------------------delphi中 过程如下-----------------------procedure TForm1.Button1Click(Sender: TObject);
var
strTMP :string;
ierr :Integer;
errmessage,strdata:PChar;
begin button1.Enabled:=false;
strdata:=PChar(Edit1.Text);
if strdata='' then
begin
Application.MessageBox(PChar('传递数据不能为空!'),'信息提示',MB_OK+MB_ICONERROR);
Exit;
end else
begin
strtmp:='';
strtmp:= CheckUSB ;//返回值为string 检查是否都有插入usb设备,如果都有则返回空,否则返回具体信息
//通过这个函数获得usb的各个端口句柄值(本窗体公共变量),供传给getdata函数用
if strtmp <>'' then
begin
Application.MessageBox(PChar(strtmp),'信息提示',MB_OK+MB_ICONERROR);
Exit;
end else //调用动态库函数
begin
try
flag:='0101010';
ierr:=$9000;
// GetMem(ErrMessage,1023);
SB.Panels[0].Text:='正在通信...';
screen.Cursor:=crHourGlass;
ierr:=getdata(l_cominfoUSB1,l_cominfoUSB1,l_cominfoUSB2,l_cominfoUSB2,l_cominfoUSB3,l_cominfoUSB3,l_cominfoUSB4,strdata,errmessage); //调用dll中 函数
finally
screen.Cursor:=crdefault;
button1.Enabled:=true;
end;
if ierr=$9000 then
begin
try
SB.Panels[0].Text:='检查完毕!'; //程序一般在这报错
showmessage('OK') ; //注释掉上行则本行报错
ct_close(l_cominfoUSB1);//关闭端口
ct_close(l_cominfoUSB2);
ct_close(l_cominfoUSB3);
ct_close(l_cominfoUSB4); except
end;
end
else
begin
SB.Panels[0].Text:='通信失败!';
try
ct_close(l_cominfoUSB1);
ct_close(l_cominfoUSB2);
ct_close(l_cominfoUSB3);
ct_close(l_cominfoUSB4);
except
end;
end;
end;
end;
end;
谢谢你 现在不知道怎么办,你看还不要什么要提供的?
没调试过你这个程序,现在只能是猜;
strdata:=PChar(Edit1.Text);
这一句没分配内存,
getdata(l_cominfoUSB1,l_cominfoUSB1,l_cominfoUSB2,l_cominfoUSB2,l_cominfoUSB3,l_cominfoUSB3,l_cominfoUSB4,strdata,errmessage)中的strdata有可能调用出错了。
你改一下试试:
var strdata:array[0..1023] of char;
edit1.GetTextBuf(strdata,1024);
1、要是标准win32 DLL
2、errmessage 传递的是一个野指针
3、尝试一下先释放USB口,完成DLL中的操作后再设置UI界面。
换个类型,STRINGBULDIER看看行不。
http://blog.donews.com/keo321/archive/2008/07/17/1321048.aspx以前用VC写的ATL控件也是出现指针错误,用vb,C#侧过没有问题,就是delphi调用时有问题。后来在 delphi中设置 Delphi: const MCW_EM = DWord($133f);
begin
Set8087CW(MCW_EM);
end;
才解决了,试试看!
衷心感谢 :xiaoxiao_8