如何将C语言程序转译成delphi语言程序.docx
《如何将C语言程序转译成delphi语言程序.docx》由会员分享,可在线阅读,更多相关《如何将C语言程序转译成delphi语言程序.docx(29页珍藏版)》请在冰豆网上搜索。
如何将如何将C语言程序转译成语言程序转译成delphi语言程序语言程序目录Delphi指针与C指针区别2一、类型指针的定义。
2二、无类型指针的定义。
2三、指针的解除引用。
2四、取地址(指针赋值)。
3五、指针运算。
3六、动态内存分配。
3七、字符数组的运算。
4八、函数指针。
4九.数据类型对照表5十.关键字对照表6如何将C/C+程序转译成Delphi81c头文件分解82基本转换82.1名字82.2单元附属82.3#defines和constants93数据类型93.1基本数据类型93.2winapi公共类型103.3数组113.4字符串113.5枚举类型:
113.6结构、记录124.宏命令155条件句166函数166.1基本的166.2调用约定167.连接177.1静态链接177.2动态链接188公共支持单元20Delphi指针与指针与C指针区别指针区别大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上。
因此,说指针是C语言的灵魂,一点都不为过。
同时,这种说法也让很多人产生误解,似乎只有C语言的指针才能算指针。
Basic不支持指针,在此不论。
其实,Pascal语言本身也是支持指针的。
从最初的Pascal发展至今的ObjectPascal,可以说在指针运用上,丝毫不会逊色于C语言的指针。
以下内容分为八个部分,分别是一、类型指针的定义二、无类型指针的定义三、指针的解除引用四、取地址(指针赋值)五、指针运算六、动态内存分配七、字符数组的运算八、函数指针九、数据类型对照表十、关键字对照表一、类型指针的定义。
一、类型指针的定义。
对于指向特定类型的指针,在C中是这样定义的:
int*ptr;char*ptr;与之等价的ObjectPascal是如何定义的呢?
varptr:
Integer;ptr:
char;其实也就是符号的差别而已。
二、无类型指针的定义。
二、无类型指针的定义。
C中有void*类型,也就是可以指向任何类型数据的指针。
ObjectPascal为其定义了一个专门的类型:
Pointer。
于是,ptr:
Pointer;就与C中的void*ptr;等价了。
三、指针的解除引用。
三、指针的解除引用。
要解除指针引用(即取出指针所指区域的值),C的语法是(*ptr),ObjectPascal则是ptr。
四、取地址(指针赋值)。
四、取地址(指针赋值)。
取某对象的地址并将其赋值给指针变量,C的语法是ptr=&Object;ObjectPascal则是ptr:
=Object;也只是符号的差别而已。
五、指针运算。
五、指针运算。
在C中,可以对指针进行移动的运算,如:
chara20;char*ptr=a;ptr+;ptr+=2;当执行ptr+;时,编译器会产生让ptr前进sizeof(char)步长的代码,之后,ptr将指向a1。
ptr+=2;这句使得ptr前进两个sizeof(char)大小的步长。
同样,我们来看一下ObjectPascal中如何实现:
vara:
array1.20ofChar;ptr:
PChar;/PChar可以看作Charbeginptr:
=a;Inc(ptr);/这句等价于C的ptr+;Inc(ptr,2);/这句等价于C的ptr+=2;end;六、动态内存分配。
六、动态内存分配。
C中,使用malloc()库函数分配内存,free()函数释放内存。
如这样的代码:
int*ptr,*ptr2;inti;ptr=(int*)malloc(sizeof(int)*20);ptr2=ptr;for(i=0;i20;i+)*ptr=i;ptr+;free(ptr2);ObjectPascal中,动态分配内存的函数是GetMem(),与之对应的释放函数为FreeMem()(传统Pascal中获取内存的函数是New()和Dispose(),但New()只能获得对象的单个实体的内存大小,无法取得连续的存放多个对象的内存块)。
因此,与上面那段C的代码等价的ObjectPascal的代码为:
varptr,ptr2:
integer;i:
integer;beginGetMem(ptr,sizeof(integer)*20);/这句等价于C的ptr=(int*)malloc(sizeof(int)*20);ptr2:
=ptr;/保留原始指针位置fori:
=0to19dobeginptr:
=i;Inc(ptr);end;FreeMem(ptr2);end;对于以上这个例子(无论是C版本的,还是ObjectPascal版本的),都要注意一个问题,就是分配内存的单位是字节(BYTE),因此在使用GetMem时,其第二个参数如果想当然的写成20,那么就会出问题了(内存访问越界)。
因为GetMem(ptr,20);实际只分配了20个字节的内存空间,而一个整形的大小是四个字节,那么访问第五个之后的所有元素都是非法的了(对于malloc()的参数同样)。
七、字符数组的运算。
七、字符数组的运算。
C语言中,是没有字符串类型的,因此,字符串都是用字符数组来实现,于是也有一套str打头的库函数以进行字符数组的运算,如以下代码:
charstr15;char*pstr;strcpy(str,teststr);strcat(str,_testok);pstr=(char*)malloc(sizeof(char)*15);strcpy(pstr,str);printf(pstr);free(pstr);而在ObjectPascal中,有了String类型,因此可以很方便的对字符串进行各种运算。
但是,有时我们的Pascal代码需要与C的代码交互(比如:
用ObjectPascal的代码调用C写的DLL或者用ObjectPascal写的DLL准备允许用C写客户端的代码)的话,就不能使用String类型了,而必须使用两种语言通用的字符数组。
其实,ObjectPascal提供了完全相似C的一整套字符数组的运算函数,以上那段代码的ObjectPascal版本是这样的:
varstr:
array1.15ofchar;pstr:
PChar;/Pchar也就是CharbeginStrCopy(str,teststr);/在C中,数组的名称可以直接作为数组首地址指针来用/但Pascal不是这样的,因此str前要加上取地址的运算符StrCat(str,_testok);GetMem(pstr,sizeof(char)*15);StrCopy(pstr,str);Write(pstr);FreeMem(pstr);end;八、函数指针。
八、函数指针。
在动态调用DLL中的函数时,就会用到函数指针。
假设用C写的一段代码如下:
typedefint(*PVFN)(int);/定义函数指针类型intmain()HMODULEhModule=LoadLibrary(test.dll);PVFNpvfn=NULL;pvfn=(PVFN)GetProcAddress(hModule,Function1);pvfn
(2);FreeLibrary(hModule);就我个人感觉来说,C语言中定义函数指针类型的typedef代码的语法有些晦涩,而同样的代码在ObjectPascal中却非常易懂:
typePVFN=Function(para:
Integer):
Integer;varfn:
PVFN;/也可以直接在此处定义,如:
fn:
function(para:
Integer):
Integer;hm:
HMODULE;beginhm:
=LoadLibrary(test.dll);fn:
=GetProcAddress(hm,Function1);fn
(2);FreeLibrary(hm);end;Delphi构造函数中抛出异常会自动先调用析构函数Delphi里,如果构造函数中抛出了异常,则会自动先执行析构函数,然后再把异常向外抛出;而在C里,构造函数中若有异常抛出,则析构函数是不会被调用的。
Delphi简化了COM接口中的AddRef、Release和QueryInterfaceC里一般用模板对COM接口进行封装,而在Delphi里,AddRef、Release以及QueryInterface都被编译器隐藏掉了,当把一个IUnknown类型的变量(本质上也是一个指针)赋值给另一个变量时,编译器在背后自动AddRef,当一个IUnknown变量离开作用域的时候(再也没有人使用它),Release被自动调用,而QueryInterface被抽象为AS运算符:
软件开发网procedureFoo(constAParam:
IUnknown);varbar:
IUnknown;other:
IStream;beginbar:
=AParam;/AParam指向的实例由于赋值操作被AddRef一次other:
=barasIStream;/调用了一次QueryInterface,引用计数再次加一end;/返回时,other和bar都离开作用域,分别被调用Release各一次C中用模板(比如_com_ptr)也可以使引用计数自动化,不过QueryInterface就没那么方便了。
九九.数据类型对照表数据类型对照表序号C/C+类型ObjectPascal类型序号C/C+类型ObjectPascal类型1unsignedshortintWord12charChar2signedshortintSmallInt13signedcharShortInt3unsignedintCardinal3.25fix14unsignedcharByte4signedintInteger15char*PChar5UINTLongIntorCardinal16LPSTRorPSTRPChar6WORDWord17LPWSTRorPWSTRPWideChar3.12fix7DWORDLongIntorCardinal18void*Pointer8unsignedlongLongIntorCardinal19BOOLBool9unsignedlongintLongIntorCardinal20floatSingle10signedlongLongInt21doubleDouble11signedlongintLongInt22longdoubleExtended十十.关键字对照表关键字对照表LP,NP,PP,P前缀:
iffirst=TthenTbecomesPelseP前缀x序号C/C+类型ObjectPascal类型序号C/C+类型ObjectPascal类型1HANDLETHandle39ABCTABC2FARPROCTFarProc40RASTERIZER_STATUSTRasterizer_Status3ATOMTAtom41MOUSEHOOKSTRUCTTMouseHookStruct4TPOINTTPoint42CBTACTIVATESTRUCTTCBTActivateStruct5TRECTTRect43HARDWAREHOOKSTRUCTTHardwareHookStruct6COLORREFTColorRef44EVENTMSGTEventMsg7OFSTRUCTTOFStruct45WNDCLASSTWndClass8DEBUGHOOKINFOTDebugHookInfo46MSGTMsg9BITMAPTBitMap47MINMAXINFOTMinMaxInfo10RGBTRIPLETRGBTriple48SEGINFOTSegInfo11RGBQUADTRGBQuad49ACCELTAccel12BITMAPCOREHEADERTBitmapCoreHeader50PAINTSTRUCTTPaintStruct13BITMAPINFOHEADERTBitmapInfoHeader51CREATESTRUCTTCreateStruct14BITMAPINFOTBitmapInfo52CBT_CREATEWNDTCBT_CreateWnd15BITMAPCOREINFOTBitmapCoreInfo53MEASUREITEMSTRUCTTMeasureItemStruct16BITMAPFILEHEADERTBitmapFileHeader54DRAWITEMSTRUCTTDrawItemStruct17HANDLETABLETHandleTable55DELETEITEMSTRUCTTDeleteItemStruct18METARECORDTMetaRecord56COMPAREITEMSTRUCTTCompareItemStruct19METAHEADERTMetaHeader57WINDOWPOSTWindowPos20METAFILEPICTTMetaFilePict58WINDOWPLACEMENTTWindowPlacement21TEXTMETRICTTextMetric59NCCALCSIZE_PARAMSTNCCalcSize_Params22NEWTEXTMETRICTNewTextMetric60SIZETSize23LOGBRUSHTLogBrush61MENUITEMTEMPLATEHEADERTMenuItemTemplateHeader24LOGPENTLogPen62MENUITEMTEMPLATETMenuItemTemplate25PATTERNTPatternTLogBrush63DCBTDCB26PALETTEENTRYTPaletteEntry64COMSTATTComStat27LOGPALETTETLogPalette65MDICREATESTRUCTTMDICreateStruct28LOGFONTTLogFont66CLIENTCREATESTRUCTTClientCreateStruct29ENUMLOGFONTTEnumLogFont67MULTIKEYHELPTMultiKeyHelp30PANOSETPanose68HELPWININFOTHelpWinInfo31KERNINGPAIRTKerningPair69CTLSTYLETCtlStyle32OUTLINETEXTMETRICTOutlineTextMetric70CTLtypeTCtltype33FIXEDTFixed71CTLINFOTCtlInfo34MAT2TMat272DDEADVISETDDEAdvise35GLYPHMETRICSTGlyphMetrics73DDEDATATDDEData36POINTFXTPointFX74DDEPOKETDDEPoke37TTPOLYCURVETTTPolyCurve75DDEAACKTDDEAck38TTPOLYGONHEADERTPolygonHeader76DEVMODETDevMode77KANJISTRUCTTKanjiStruct如何将如何将C/C+程序转译成程序转译成Delphi1c头文件分解头文件分解2基本转换基本转换2.1名字名字该c-程序通常用大写字母类型标识符,例如MY_TYPE。
在Delphi中,类型标识符是有T开头加上类型名称组成,不使用下划线。
C类型标识符MY_TYPE的Delphi类型是TMyType。
在C早期的头文件的指针类型为LPMY_TYPE。
翻译成Delphi应该是PMyType才符合Borland的风格。
常量的命名通常与原来的名称,包括大写字母和下划线。
以下是一些实例CDelphi-翻译typedefstruct_IMAGE_FILE_HEADERWORDMachine;WORDNumberOfSections;DWORDTimeDateStamp;DWORDPointerToSymbolTable;DWORDNumberOfSymbols;WORDSizeOfOptionalHeader;WORDCharacteristics;IMAGE_FILE_HEADER,*PIMAGE_FILE_HEADER;typePImageFileHeader=TImageFileHeader;TImageFileHeader=packedrecordMachine:
Word;NumberOfSections:
Word;TimeDateStamp:
DWORD;PointerToSymbolTable:
DWORD;NumberOfSymbols:
DWORD;SizeOfOptionalHeader:
Word;Characteristics:
Word;end;#defineLANG_NEUTRAL0x00#defineLANG_AFRIKAANS0x36#defineLANG_ALBANIAN0x1C#defineLANG_ARABIC0x01#defineLANG_BASQUE0x2D#defineLANG_BELARUSIAN0x23#defineLANG_BULGARIAN0x02#defineLANG_CATALAN0x03#defineLANG_CHINESE0x04CONSTLANG_NEUTRAL=$00;LANG_AFRIKAANS=$36;LANG_ALBANIAN=$1C;LANG_ARABIC=$01;LANG_BASQUE=$2D;LANG_BELARUSIAN=$23;LANG_BULGARIAN=$02;LANG_CATALAN=$03;LANG_CHINESE=$04;2.2单元附属单元附属C和C+使用#include在另一头文件和源文件包含头文件。
Delphi是引用单元(在USES中引用)代替头文件。
例如:
D3D.HincludesD3DTYPES.H,D3DCAPS.HD3DTYPES.HincludesDDRAW.H一个单元包含一个头文件的翻译,所以D3DTYPES.H和D3DCAPS.H被请求并入D3D.H因此翻译成delphi,则是D3D.PASUSES需要D3DTYPES.PAS,D3DCAPS.PAS。
在windows.pasBorland已经为我们做了很多工作。
Borland的Windows单元包含了大部分的基本的Windows的数据类型,所以任何翻译单元需要Windows数据类型需要在其USES中引用Windows单元。
注意:
在Delphi1,为windows.pas替代winprocs.pas和wintypes.pas,因为这两个单元包括在windows.pas的Delphi32位版本定义的Delphi16位。
在Delphi2中,为了向后兼容,这两个文件在Delphi的32位版本中也被当作windows.pas。
一些头文件包含源码不被直接翻译成Pascal语言,但头文件在汇编上的影响必须纳入翻译代码。
例如,PSHPACK.H包含编译器指令,不能直接翻译到Delphi;PSHPACK4.H指示编译器使用4字节的包。
2.3#defines和和constantsC语言中#define被用于:
声明一个常量;声明一个条件编译的符号;声明一个宏;C语言中常量的声明如下:
#defineNameOfConstantValue例如:
#defineTIME_ZONE_ID_UNKNOWN0#defineTIME_ZONE_ID_STANDARD1#defineTIME_ZONE_ID_DAYLIGHT2翻译成delphi:
CONSTTIME_ZONE_ID_UNKNOWN=0;TIME_ZONE_ID_STANDARD=1;TIME_ZONE_ID_DAYLIGHT=2;2.3.116进制的值进制的值C语言#defineMY_CONSTANT0xFFDelphi语言:
CONSTMY_CONSTANT=$FF;3数据类型数据类型3.1基本数据类型基本数据类型CDelphiUNSIGNEDLONGDword(Longint)UNSIGNEDSHORTwordINTintegerUNSIGNEDCHARbyte,char(Dependingonusage)3.2winapi公共类型公共类型WindowsAPI定义了一些常见API类型。
这是建议的名称,翻译尽可能使用。
windows.pas声明了许多这些类型,其中一些如下:
APIType声明在DELPHI中用法Type说明ULONGULongDWordPULONGPULongDWordUSHORTUShortSmallIntPUSHORTPUShortSmallIntUCHARUCharBytePUCHARPUCharByteDWORDDWordDWordPDWORD,LPDWORDPDWordDWordBOOLBoolBoolPBOOL,LPBOOLPBoolBoolBYTEByteBytePBYTE,LPBYTEPByteByteWORDWordWordPWORD,LPWORDPwordWordINTIntegerIntegerPINT,LPINTPIntegerIntegerLPVOIDPointerUntypedPointerUINTUIntIntegerPUINT,LPUINTPUIntIntegerWCHARWCharWideCharPWCHAR,LPWCHAR,PCWCH,LPCWCH,NWPSTR,PWCharWideCharPWSTR,LPWSTRLPWStrWideCharPCWSTR,LPCWSTRLPCWStrWideCharPCH,LPCHPCharCharPSTR,LPSTRLPStrCharPCSTR,LPCSTRLPCStrCharHANDLETHandleDWordPHANDLE,LPHANDLEPHandleDWord3.3数组数组方法1C语言中的数组:
DWORDMyType4翻译成DELPHI如下:
MyType=Array0.3ofDWord;