全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1140
推到 Plurk!
推到 Facebook!

请教各位大哥,一个 DLL 的调用问题,谢谢!

尚未結案
lsh998
中階會員


發表:163
回覆:138
積分:60
註冊:2005-01-07

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-03-17 13:22:37 IP:219.128.xxx.xxx 未訂閱
有 C 语言写的 DLL 如下: short WINAPI u_SetDeviceMode(COMDATA &, DEVICEMODE &) 设定设备工作模式 short WINAPI u_OpenCom(short, short) 打开指定串口 请教 short WINAPI u_OpenCom(short, short) 中的 short 在 DELPHI 中怎么表示啊? 还有 short WINAPI u_SetDeviceMode(COMDATA &, DEVICEMODE &) 中的 (COMDATA &, DEVICEMODE &) 是什么意思啊? function WINAPIu_OpenCom(a:integer;b:integer):integer;stdcall; 我这样表示肯定是错误的 请个为大哥给我写个列子: short WINAPI u_SetDeviceMode(COMDATA &, DEVICEMODE &) 设定设备工作模式 short WINAPI u_OpenCom(short, short) 打开指定串口 在 DELPHI 中的写法,好吗? 谢谢各位大哥!
yorkland
高階會員


發表:2
回覆:138
積分:108
註冊:2004-12-17

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-03-17 13:37:19 IP:220.130.xxx.xxx 未訂閱
Short在Delphi裡頭是ShortInt 宣告方式應該像底下範例.. funciton u_SetDeviceMode(var X: TCOMDATA, var Y: TDEVICEMODE): Short; stdcall; 设定设备工作模式 function u_OpenCom(X1: shortint, X2: shortint): Short; stdcall; 打开指定串口 其中的TCOMDATA與TDEVICEMODE應該是自訂型別, 然後以傳址的方式處理參數。
wyndog
資深會員


發表:7
回覆:362
積分:348
註冊:2004-10-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-03-17 13:47:50 IP:60.248.xxx.xxx 未訂閱
引言: Short在Delphi裡頭是ShortInt 宣告方式應該像底下範例..
剛我的直覺也是這樣,後來查了一下,才發覺,還好有查 :p Delphi 的 ShortInt 是 8bit 有號數,-128~127 所以,應該要把 Short 換成 SmallInt (16bit 有號數) 好奇怪的 DLL,很少看到用 short 的...
lsh998
中階會員


發表:163
回覆:138
積分:60
註冊:2005-01-07

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-03-17 16:35:35 IP:219.128.xxx.xxx 未訂閱
非常感谢 yorkland 和 wyndog 大哥 short WINAPI u_SetDeviceMode(COMDATA &, DEVICEMODE &) 输入参数: COMDATA结构 : ComPort 通信串口号 1 - 255 Address 设备地址 0 - 255 ReData 函数输出值 (100 Bytes) DEVICEMODE结构 : DeviceType 设备类型 (1 Byte ’0’ - 读写器 ‘1’ - 发卡器 ‘2’ - 充值机 ‘3’ - 读卡器) OutPutMode 输出模式 (1 Byte ’0’ - 韦根输出 ‘1’ - RS232/RS422输出) 函数返回值: 000: 通信成功。 242: 命令执行出错,返回错误代码。 160: 硬件返回系统错误。 其它: 通信失败,具体返回值含义请参阅返回值代码表 函数描述: 设定设备工作模式。 输出值格式(函数执行成功): “1B” 我在 delphi 这样写: unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type COMDATA=record ComPort:integer; Address:integer; ReData:integer; end; type DEVICEMODE=record DeviceType:byte; OutPutMode:byte; end; function u_SetDeviceMode(const date:COMDATA;const mode:DEVICEMODE):word;stdcall; implementation function u_SetDeviceMode(const date:COMDATA;const mode:DEVICEMODE):word;external 'GSHW.dll'; end. //现在我要调用 u_SetDeviceMode ,但是我不知道怎么输入参数啊? procedure TForm1.Button1Click(Sender: TObject); begin u_SetDeviceMode ( ,);//这里面的参数输入什么东西呢?请举个列子好吗? end; 谢谢!
wyndog
資深會員


發表:7
回覆:362
積分:348
註冊:2004-10-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-03-17 16:50:35 IP:60.248.xxx.xxx 未訂閱
type
  TCOMDATA = record
    ComPort: integer;
    Address: integer;
    ReData:  integer;
  end;      TDEVICEMODE = record
    DeviceType: byte;
    OutPutMode: byte;
  end;    funciton u_SetDeviceMode(var X: TCOMDATA; var Y: TDEVICEMODE): Word; stdcall;    var
  DEVICEMODE: TDEVICEMODE;
  COMDATA: TCOMDATA;    begin
  u_SetDeviceMode(COMDATA, DEVICEMODE);
1. 原來的宣告,參數的部份有 & 表示是傳值過去 所以,改成 Delphi 時,要在前面加上 var 2. 你的 COMDATA 看起來怪怪的 ReData 輸出 100bytes 怎麼是宣告成 integer ?
yorkland
高階會員


發表:2
回覆:138
積分:108
註冊:2004-12-17

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-03-17 16:53:57 IP:220.130.xxx.xxx 未訂閱
不好意思, 給了錯的訊息, 的確要修改成smallint才對。    有幾個地方要留意一下.. 1. 你使用const表示數值在函式裡只能讀取, 不能修改。 2. 如果你是用record宣告, 要確認一下是否需要加packed, 因為會跟參數的Bytes長度有關。    
type
  COMDATA = packed record
    ComPort:integer;
    Address:integer;
    ReData:integer;
  end;    procedure TForm1.Button1Click(Sender: TObject);
var
  Device: DEVICEMODE;
  Com: COMDATA;
begin
  u_SetDeviceMode(Com, Device);
end;
lsh998
中階會員


發表:163
回覆:138
積分:60
註冊:2005-01-07

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-03-17 17:13:40 IP:219.128.xxx.xxx 未訂閱
非常感谢 wyndog 和 yorkland 大哥 我先搞错了 在 C 语言中的结构为: typedef struct _DEVICEMODE{ unsigned char DeviceType; unsigned char OutPutMode; }DEVICEMODE; Public Type DEVICEMODE DeviceType As String * 1 OutPutMode As String * 1 End Type 我在 delphi 中是怎么表示的呢? 谢谢!
wyndog
資深會員


發表:7
回覆:362
積分:348
註冊:2004-10-12

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-03-17 17:53:42 IP:60.248.xxx.xxx 未訂閱
  TDEVICEMODE = packed record
    DeviceType: byte;
    OutPutMode: byte;
  end;
跟隨 yorkland 兄的腳步,加個 packed 上去 :p 基本上,DEVICEMODE 是沒問題啦 重點是另一個
lsh998
中階會員


發表:163
回覆:138
積分:60
註冊:2005-01-07

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-03-18 08:38:46 IP:219.128.xxx.xxx 未訂閱
大哥真是诲人不卷 忠心感谢大哥。 大哥,加個 packed 上去 有什么用啊?
wyndog
資深會員


發表:7
回覆:362
積分:348
註冊:2004-10-12

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-03-18 09:26:40 IP:60.248.xxx.xxx 未訂閱
引言: 加個 packed 上去 有什么用啊?
因為 Win32 程式的關係,為了最佳化 會把結構中的項目調成佔用 4(or 偶數) 倍數的空間 比如說,DEVICEMODE 裡是二個元素,各佔一個 byte 在 Win32 程式裡,Compiler 可能會把它調整成各佔用 4 bytes(1 dword) 那這樣做的話,就會跟 DLL 要用的不一樣,會有問題 雖然我記得預設就是 packed 了,不過,加一下也是比較保險就是了 還有另一個方法是加上 {$A-} or {$A1} 如果不確定的話,可以 sizeof 那個結構看看 正常的話,會是 2,如果被調過,就會變成 8
系統時間:2024-07-01 5:43:53
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!