小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

在Delphi編程中使用C語言代碼

 獨(dú)孤求財(cái) 2012-03-20

在Delphi編程中使用C語言代碼

時(shí)間:2011-5-26來源:yang 作者: peng點(diǎn)擊: 5次


在Delphi編程中使用C語言代碼 

  
   Windows下編程的工具有很多,例如VB,Delphi,VC等等.我在這里不想討論"它們的具體哪個(gè)更好一點(diǎn)"這種幼稚的問題.玩過DOS程序設(shè)計(jì)的人都知道,DOS下很多語言的實(shí)質(zhì)核心還是調(diào)用系統(tǒng)提供的匯編中斷函數(shù).到了Windows下,它就變成了我們常說的API了.而在Windows下寫程序很多時(shí)候都是調(diào)用API,語言,只不過是一個(gè)表達(dá)工具而已.
   我現(xiàn)在已經(jīng)參加工作大約有半年左右,我們公司是用Borland公司的Delphi作為主開發(fā)工具.本著未偏袒任何一個(gè)工具的立場(chǎng),我說句公道話:Delphi是目前Win32下開發(fā)程序的最快速,最有效率的工具.
   Delphi適合用來開發(fā)應(yīng)用程序,但是有時(shí)侯一些底層的東西可以直接使用C語言來開發(fā).我在公司經(jīng)常開發(fā)跟硬件相關(guān)的項(xiàng)目,而很多硬件的SDK包是用C來寫的.這個(gè)時(shí)候我一般把它們轉(zhuǎn)換成Delphi(PASCAL)語法的代碼.下面談一下我的個(gè)人粗淺經(jīng)驗(yàn).因?yàn)楫?dāng)時(shí)學(xué)校教的是Pascal語言,所以我對(duì)C語言并不是太熟手.下面的觀點(diǎn)或者代碼如有錯(cuò)漏之處希望高手們放小弟一馬:)
一:將C語言的程序編譯成DLL供Delphi調(diào)用.這種方法過于簡單,而且需要額外帶一個(gè)DLL文件,所以不在本文的討論范圍之內(nèi).

二:直接轉(zhuǎn)換C語言代碼到DELPHI代碼


  C語言的函數(shù)格式與Delphi不同,它們是函數(shù)返回類型在前,函數(shù)聲明在后.對(duì)于沒有任何返回類型的函數(shù)則定義為VOID類型.
  例如:Delphi中函數(shù)function MyFunction:(intIN:integer):Bool;相應(yīng)的C語言代碼就變成Bool MyFunction(int intIN);又例如procedure MyProcedure;====>void MyProcedure;采用這種方法,一般要求對(duì)C語言比較熟悉.我一般是采用這種方法.下面是我收集整理的自己常用的Delphi與C之間的類型對(duì)應(yīng)表.其中左邊是C類型,右邊是對(duì)應(yīng)的Delphi類型:

ABC -> TABC
ACCEL -> TAccel
ATOM -> TAtom
BITMAP -> TBitMap
BITMAPCOREHEADER -> TBitmapCoreHeader
BITMAPCOREINFO -> TBitmapCoreInfo
BITMAPFILEHEADER -> TBitmapFileHeader
BITMAPINFO -> TBitmapInfo
BITMAPINFOHEADER -> TBitmapInfoHeader
BOOL -> Bool
CBT_CREATEWND -> TCBT_CreateWnd
CBTACTIVATESTRUCT -> TCBTActivateStruct
CHAR -> Char
CHAR* -> PChar
CLIENTCREATESTRUCT -> TClientCreateStruct
COLORREF -> TColorRef
COMPAREITEMSTRUCT -> TCompareItemStruct
COMSTAT -> TComStat
CREATESTRUCT -> TCreateStruct
CTLINFO -> TCtlInfo
CTLSTYLE -> TCtlStyle
CTLtype -> TCtltype
DCB -> TDCB
DDEAACK -> TDDEAck
DDEADVISE -> TDDEAdvise
DDEDATA -> TDDEData
DDEPOKE -> TDDEPoke
DEBUGHOOKINFO -> TDebugHookInfo
DELETEITEMSTRUCT -> TDeleteItemStruct
DEVMODE -> TDevMode
DOUBLE -> Double
DRAWITEMSTRUCT -> TDrawItemStruct
DWORD -> LongInt
ENUMLOGFONT -> TEnumLogFont
EVENTMSG -> TEventMsg
FARPROC -> TFarProc
FIXED -> TFixed
FLOAT -> Single
GLYPHMETRICS -> TGlyphMetrics
HANDLE -> THandle
HANDLETABLE -> THandleTable
HARDWAREHOOKSTRUCT -> THardwareHookStruct
HELPWININFO -> THelpWinInfo
INT -> Integer
KERNINGPAIR -> TKerningPair
LOGBRUSH -> TLogBrush
LOGFONT -> TLogFont
LOGPALETTE -> TLogPalette
LOGPEN -> TLogPen
LONG -> LongInt
LONG DOUBLE -> Extended
LONG INT -> LongInt
LPSTR -> PChar
LPWSTR -> PWideChar
MAT2 -> TMat2
MDICREATESTRUCT -> TMDICreateStruct
MEASUREITEMSTRUCT -> TMeasureItemStruct
MENUITEMTEMPLATE -> TMenuItemTemplate
MENUITEMTEMPLATEHEADER -> TMenuItemTemplateHeader
METAFILEPICT -> TMetaFilePict
METAHEADER -> TMetaHeader
METARECORD -> TMetaRecord
MINMAXINFO -> TMinMaxInfo
MOUSEHOOKSTRUCT -> TMouseHookStruct
MSG -> TMsg
MULTIKEYHELP -> TMultiKeyHelp
NCCALCSIZE_PARAMS -> TNCCalcSize_Params
NEWTEXTMETRIC -> TNewTextMetric
OFSTRUCT -> TOFStruct
OUTLINETEXTMETRIC -> TOutlineTextMetric
PAINTSTRUCT -> TPaintStruct
PALETTEENTRY -> TPaletteEntry
PANOSE -> TPanose
PATTERN -> TPattern
POINTFX -> TPointFX
PSTR -> PChar
PWSTR -> PWideChar
RASTERIZER_STATUS -> TRasterizer_Status
RGBQUAD -> TRGBQuad
RGBTRIPLE -> TRGBTriple
SEGINFO -> TSegInfo
SHORT -> SmallInt
SHORT INT -> SmallInt
SIZE -> TSize
TEXTMETRIC -> TTextMetric
TPOINT -> TPoint
TRECT -> TRect
TTPOLYCURVE -> TTTPolyCurve
TTPOLYGONHEADER -> TPolygonHeader
UINT -> Word
UNSIGNED -> Word
UNSIGNED CHAR -> Byte
UNSIGNED INT -> Word
UNSIGNED LONG -> LongInt(DWORD)
UNSIGNED LONG INT -> LongInt
UNSIGNED SHORT -> Word
UNSIGNED SHORT INT -> Word
VOID* -> Pointer
WINDOWPLACEMENT -> TWindowPlacement
WINDOWPOS -> TWindowPos
WNDCLASS -> TWndClass
WORD -> Word

三:在Delphi中直接鏈接C語言的OBJ文件.
  這種方法的好處在于最終EXE不用帶任何外部文件.也不用對(duì)C語言過于熟悉.
  我們都知道,代碼在編譯成可執(zhí)行文件(或DLL,OCX文件,下同)之前,都必須得先生成OBJ文件(DELPHI一般是DCU文件,但也可以通過編輯編譯選項(xiàng)生成OBJ文件),然后把OBJ文件和資源文件(*.RES)鏈接成最終的可執(zhí)行文件.利用這個(gè)方法,我們可以直接把OBJ文件鏈接到我們的程序里面.
  不過需要注意的是,編譯器不同,生成的OBJ文件也不一樣.Microsoft的編譯器生成的OBJ文件是COFF格式,而Borland的C++Builder生成的是OMF格式.因?yàn)槲覀冃枰贒elphi中鏈接,所以必須使用CBC,或者Borland官方站點(diǎn)帶的免費(fèi)編譯工具.下面我們通過一個(gè)簡單的例子來說明具體操作步驟:
  這個(gè)例子是簡單的提供一個(gè)函數(shù),用來判斷一個(gè)文件是否為Dat格式的VCD文件.頭文件聲明如下:


/*
文件名稱:DatFormat.h
*/
#ifndef DatFormat_H
#define DatFormat_H
#include <windows.h>
#pragma pack(push, 1)//這個(gè)與下面的配對(duì),一般用到記錄類型的時(shí)候需要定義,這里實(shí)際不用


#ifdef __cplusplus
extern "C" {
#endif

extern BOOL CheckIsDatFile(const char * FileName,BOOL *IsDatFile);

#ifdef __cplusplus
}
#endif


#pragma pack(pop)

#endif // DatFormat_H

 具體實(shí)現(xiàn)代碼DatFormat.c如下:

#include "DatFormat.h"
BOOL CheckIsDatFile(const char * FileName,BOOL *IsDatFile)
/*
函數(shù)說明:該函數(shù)用于判斷一個(gè)文件是否為Dat文件(即VCD文件)格式.
參數(shù):
IN:
FileName:欲判斷的文件名稱
IN,OUT:
IsDatFile:是否為Dat格式文件
OUT:
讀文件失敗返回FALSE,否則返回TRUE.
------------------------------------
作者:陳經(jīng)韜.2004,01,17. http://www.,lovejingtao@21cn.com/
*/
{
HANDLE hFile;
DWORD dwBytesRead;
BOOL re;
char MyBuf[4];

*IsDatFile=FALSE;

//建立讀文件句柄
hFile = CreateFile(FileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
0);


if (hFile == INVALID_HANDLE_VALUE) return FALSE;

//讀文件
re = ReadFile(hFile,
&MyBuf,
4,
&dwBytesRead,
NULL);

if (dwBytesRead!=4)
{
CloseHandle(hFile);
return FALSE;
}

//讀文件失敗的時(shí)候
if (re!=TRUE)
{
CloseHandle(hFile);
return FALSE;
}
CloseHandle(hFile);
*IsDatFile=(MyBuf[0]==‘R‘ && MyBuf[1]==‘I‘ && MyBuf[2]==‘F‘ && MyBuf[3]==‘F‘);

return(TRUE);
}

 運(yùn)行CBC,新建一個(gè)工程,然后把DatFormat.c添加到工程里面,編譯整個(gè)工程,將得到我們需要的OBJ文件:DatFormat.OBJ.然后我們關(guān)閉CBC即可,因?yàn)橄旅娌辉傩枰玫剿?
 運(yùn)行Delphi,新建一個(gè)工程并保存.然后把DatFormat.OBJ拷貝到它的目錄之下.在單元的implementation下面添加如下代碼:

{$LINK ‘DatFormat.obj‘} //鏈接外部OBJ文件
function _CheckIsDatFile(const FileName:Pchar;IsDatFile:PBool):Bool;cdecl;external;//定義函數(shù).其中cdecl進(jìn)棧方式說明采用C語言格式傳遞參數(shù).external說明是個(gè)外部聲明函數(shù).

 注意函數(shù)聲明的原形與C定義的不一樣.必須在前面添加一個(gè)下劃線.原因是因?yàn)榫幾g器的鏈接符號(hào)中.C與C++是不一樣的.因?yàn)檫@個(gè)不是本文重點(diǎn),所以這里不作討論.請(qǐng)感興趣的朋友自行參閱相關(guān)資料.
 然后我們寫如下代碼調(diào)用此函數(shù):

procedure TFrmMain.Button1Click(Sender: TObject);
var
IsDatFile:Bool;
begin
if OpenDialog1.Execute then
if _CheckIsDatFile(Pchar(OpenDialog1.FileName),@IsDatFile) then
if IsDatFile then ShowMessage(‘恭喜!該文件是一個(gè)Dat格式的視頻文件!‘)
else ShowMessage(‘不好意思,該文件不是一個(gè)Dat格式的視頻文件!‘)
else ShowMessage(‘讀文件錯(cuò)誤!‘);
end;

 編譯這個(gè)程序,將得到一個(gè)干凈的可執(zhí)行EXE文件了.

四:C++Builder中使用Delphi單元

 這個(gè)實(shí)際是題外話了,不過這里還是提一提:假設(shè)我們有一個(gè)獲取BIOS密碼的Delphi單元

unit AwardBiosPas;

{=======================================================
項(xiàng)目: 在Delphi編程中使用C語言代碼- 演示程序
模塊: 獲取BIOS密碼單元
描述:
版本:
日期: 2004-01-17
作者: 陳經(jīng)韜.lovejingtao@21cn.com,http://www./
更新: 2004-01-17
=======================================================}

interface
uses
windows, SysUtils;

function My_GetBiosPassword: string;

implementation

function CalcPossiblePassword(PasswordValue: WORD): string;
var
I: BYTE;
C: CHAR;
S: string[8];

begin
I := 0;
while PasswordValue <> 0 do
begin
Inc(I);
if $263 > PasswordValue then
begin
if $80 > PasswordValue then
S[I] := CHAR(PasswordValue)
else if $B0 > PasswordValue then
S[I] := CHAR(PasswordValue and $77)
else if $11D > PasswordValue then
S[I] := CHAR($30 or (PasswordValue and $0F))
else if $114 > PasswordValue then
begin
S[I] := CHAR($64 or (PasswordValue and $0F));
if ‘0‘ > S[I] then
S[I] := CHAR(BYTE(S[I]) + 8);
end
else if $1C2 > PasswordValue then
S[I] := CHAR($70 or (PasswordValue and $03))
else if $1E4 > PasswordValue then
S[I] := CHAR($30 or (PasswordValue and $03))
else
begin
S[I] := CHAR($70 or (PasswordValue and $0F));
if ‘z‘ < S[I] then
S[I] := CHAR(BYTE(S[I]) - 8);
end;
end
else
S[I] := CHAR($30 or (PasswordValue and $3));
PasswordValue := (PasswordValue - BYTE(S[I])) shr 2;
end;

S[0] := CHAR(I);
PasswordValue := I shr 1;
while PasswordValue < I do
begin {this is to do because award starts calculating with the last letter}

C := S[BYTE(S[0]) - I + 1];
S[BYTE(S[0]) - I + 1] := S[I];
S[I] := C;
Dec(I);
end;
CalcPossiblePassword := S;
end;

function readcmos(off: byte): byte;
var
value: byte;
begin
asm
xor ax, ax
mov al, off
out 70h, al
in al, 71h
mov value, al
end;
readcmos := value;
end;

function My_GetBiosPassword: string;
var
superpw, userpw: word;
begin
if Win32Platform <> VER_PLATFORM_WIN32_NT then //不是NT
begin
pchar(@superpw)[0] := char(readcmos($1C));
pchar(@superpw)[1] := char(readcmos($1D));
pchar(@userpw)[0] := char(readcmos($64));
pchar(@userpw)[1] := char(readcmos($65));
Result:= (‘************BIOS密碼**********************‘)+#13+‘超級(jí)用戶密碼為:‘ + CalcPossiblePassword(superpw) + #13 + ‘用戶密碼為:‘ + CalcPossiblePassword(userpw);
end
else
Result := ‘用戶系統(tǒng)為NT,無法獲取BIOS密碼!‘;
end;
end.


 如何直接在CBC中使用它呢?新建一個(gè)CBC工程,然后把這個(gè)單元加到項(xiàng)目里面去.具體操作為:Add to Project--->文件類型:pascal unit(*.pas),然后Build Demo1.這個(gè)時(shí)候?qū)⒃贏wardBiosPas.pas的同目錄下生成一個(gè)AwardBiosPas.hpp文件.把它引用到我們的需要調(diào)用的單元.然后直接調(diào)用即可:
void __fastcall TFrmMain::Button1Click(TObject *Sender)
{
ShowMessage(My_GetBiosPassword());
}

五:其它方法.當(dāng)然可以用RES將C語言生成的二進(jìn)制文件,但這個(gè)方法與第一種方法差不多.優(yōu)點(diǎn)是不怕文件丟失.缺點(diǎn)是很容易被別人直接用資源修改工具打開修改.這個(gè)時(shí)候可以使用筆者寫的自制編程序工具PasAnywhere.不過這已經(jīng)是另外一個(gè)話題了.

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多