如何枚举出正在运行的App结合RApaLsSession和TApaTaskList应该可以做到. RApaLsSession: GetAppIcon() GetAppInfo()TApaTaskList: FindApp()从收件箱读取彩信图片mmslist实现了首先以listbox列表的形式列出了收件箱中的所以彩信,选择某一条彩信后可以显示出它的发送端号码和彩信的文本信息;现在我想让它显示发送端号码和彩信图片(假设我的彩信都是图片格式);请教两位应该怎么才能实现读彩信图片并显示的功能。 下面是读彩信文本信息的代码,你们参考一下: void CMmslController::GetMessageL( c*****t TDesC& aItem, TDes& aMessageText ) c*****t { //Read the message Uid from aItem TUint32 id = 0; TLex lexer( aItem ); lexer.SkipSpace(); TChar ch( lexer.Get() ); while ( ( ch != ‘\t’ ) && ( ch != 0 ) ) // Finding end of 1.st line { ch = lexer.Get(); } lexer.SkipSpace(); lexer.Val( id, EHex );if( iCurEntries->Find( id ) == KErrNotFound ) { return; }CMsvEntry* msvEntry = iSession->GetEntryL( id ); CleanupStack::PushL( msvEntry );c*****t TMsvEntry& msgEntry = msvEntry->Entry();CBaseMtm* clientMtm = iMtmReg->NewMtmL( msgEntry.iMtm ); CleanupStack::PushL( clientMtm );clientMtm->SwitchCurrentEntryL( msvEntry->EntryId() );// An instance of the TDesOverflow derived class used to suppress // the panic that would be generated if buffer length was exceeded // in calls to AppendFormat TOverrideOverFlow noOflo;// Text is located in iDescription field. aMessageText.AppendFormat( msgEntry.iDescription, &noOflo ); //aMessageText.AppendFormat( msgEntry.iDetails );CleanupStack::PopAndDestroy( 2 ); // clientMtm, msvEntry }如何让程序在安装后自动运行如何让一个程序(或是一个server)在安装后自动运行于手机中,这是非常容易的,只需在你的PKG文件中,在包含你的app或exe文件的那行末尾加上“FR,RI”。“FR”表示“File Run”,而“RI”则表示“Run during Installation”。请注意,务必要先开始rsc,aif,mbm文件的安装,然后才能是APP等(也就是在pkg文件的末尾进行app的安装)举例: “\Symbian.1\Series60\Epoc32\release\thumb\urel\MyApp.rsc” - “!:\system\apps\MyApp\MyApp.rsc” “\Symbian.1\Series60\Epoc32\release\thumb\urel\MyApp_caption.rsc” - “!:\system\apps\MyApp\MyApp_caption.rsc” “\Symbian.1\Series60\Epoc32\release\thumb\urel\MyApp.aif” - “!:\system\apps\MyApp\MyApp.aif” “\Symbian.1\Series60\Epoc32\release\thumb\urel\MyApp.app” - “!:\system\apps\MyApp\MyApp.app”,FR,RI文件类型和从属关系下图显示了在一个典型的Symbian程序中各文件的从属关系。[attach]457[/attach].hrh文件中包含所有要在.rss、.h和.cpp中使用的枚举类型。它们主要使用在应用程序的菜单、工具栏等地方,下面展示了一个典型的例子://MyApp.hrh // enum{ EMyAppCmdOpenFile = 0×6000, EMyAppCmdEdit, };按照惯例这些命令ID值的范围应该从0×6000开始向上。.rss文件中是资源文件,这些文件包括所有静态字符串、按钮、菜单和列表等的定义,都使用在应用程序UI中。此外,Nokia Series 60向导还可能生成一个.loc文件,这个文件同.rss文件很相似但只用于描述你程序中的静态字符串,利用它你可以很容易的将程序变成多语言版本。.rsg是生成的资源文件。它们是在编译时刻由资源编译器产生的,.cpp文件将包含它们以便处理资源。.mbm是symbian位图文件,它里面可以存储几个位图。.mbg是在创建.mbm时生成的。这些文件一般包含在那些使用位图的RSS文件中,一个mbg文件包括在.mbm中各位图的ID。网络通讯中正确显示中文1。经过对照GB2312/GBK编码表,在程序中定义_LIT8(KTest, “中文测试”);是GB2312/GBK编码 2。直接从输入框取出的字符串,经过按照byte分析并比较中文和unicode对照表,发现是UTF-16LE(Sixteen-bit UCS Transformation Format, little-endian byte order)编码 3,中文对服务器的传输建议统一处理成UTF8编码进行,从对话框获得的也一样处理,服务器需要对应识别过来的字符串并做处理。如何动态更改CEikLabel 的textCEikLabel* iLabelStatus;…..iLabelStatus = new (ELeave) CEikLabel; iLabelStatus->SetContainerWindowL( *this ); iLabelStatus->SetTextL( this->iStatusStr );…. //动态在这里更改 iLabelStatus->SetTextL(iStatusStr); iLabelStatus->DrawNow();如果初始化时就无法显示,请对照helloworld代码检查自己label是否设置正确;如果是进度进行中无法显示,请检查cactive是否正确执行,单步DrawNow是否被正确调用。在listbox中怎么处理所选项的事件触发事件并不是很复杂的事情, TKeyResp*****e CXXContainer::OfferKeyEventL(c*****t TKeyEvent& aKeyEvent, TEventCode aType) { TInt code = aKeyEvent.iCode; switch(code) { // is navigator button pressed case EKeyOK: { // pass the key press event to view, // then view will pass it to ui class’s handler iXXView->ProcessListEvent(iListBox->CurrentItemIndex()) ; } return (EKeyWasC*****umed); case EKeyLeftArrow : case EKeyRightArrow : return (EKeyWasC*****umed); default: // Let Listbox take care of its key handling return iListBox->OfferKeyEventL(aKeyEvent, aType) ; } }这个iXXView的ProcessListEvent()函数就是传入当前用户选择的那个list item的index。 2007-4-10 08:42 Moving pkg文件中指定多个操作系统版本pkg file定义了安装文件(sis)的内容,它包括应用程序的UID,一个支持的语言列表,目标产品的UID和打包在sis的一组文件: ; MyGame.pkg ; Specifies an installation file for MyGame ;Languages &EN ;Header #,(0×1000ABCD),1,0,0 ; Required line for Series 60 devices. Defines the target product ; UID. (0×101F6F88), 0, 0, 0, “\epoc32\release\thumb\urel\MyGame.app”-“!:\system\apps\MyGame\MyGame.app” “\epoc32\release\thumb\urel\MyGame.rsc”-“!:\system\apps\MyGame\MyGame.rsc” “\epoc32\release\thumb\urel\MyGame.mbm”-“!:\system\apps\MyGame\MyGame.mbm” “\epoc32\release\thumb\urel\MyGame.aif”-“!:\system\apps\MyGame\MyGame.aif” “..\MyGame\MyGameSample.wav”-“!:\system\apps\MyGame\MyGameSample.wav”Product UID定义了应用程序的目标环境,大部分的s60版本是向下兼容的。 参见下表: Nokia 7650 0×101F6F87 Nokia 3650 0×101F7962 Nokia 9210/9290 0×10005E33 Nokia N-gage 0×101F8A64 Siemens SX1 0×101F9071Series 60 Platform v0.9 0×101F6F88 Series 60 Platform v1.0 0×101F795F Series 60 Platform v1.1 0×101F8201 Series 60 Platform v1.2 0×101F8202 Series 60 Platform v2.0 0×101F7960如果程序需要依据各不同的平台来进行安装,那就可以使用条件语句块来处理,这时pkg里的语句如下: ; ; Files to install ; IF MachineUID=0×101fb3dd ; Nokia 6600 specific files “..\MyFiles\FileFor6600.dat”-“!:\system\apps\MyGame\MyData.dat” ELSEIF MachineUID=0×101f466a ; Nokia 3650 specific files “..\MyFiles\FileFor3650.dat”-“!:\system\apps\MyGame\MyData.dat” ELSE ; Files for other devices “..\MyFiles\FileForOthers.dat”-“!:\system\apps\MyGame\MyData.dat” ENDIF就可以生成一个支持多平台的安装文件,除了机器UID外,还有很多属性,如内存和CPU的标识:注意,机器UID和Product UID是不同的,见下: Nokia 7650 0×101F4FC3 Nokia 3650 0×101F466A Nokia 6600 0×101FB3DD Nokia 9210/9290 0×10005E33 Nokia N-Gage 0×101F8C19 Win32 Emulator 0×10005F62可以使用如下的代码来找出该设备的机器UID: #include //and link with hal.lib TInt machineUid = 0; HAL::Get(HALData::EmachineUid, machineUid);如何按字节读取文件1.RFile::Read() TInt Read(TDes8& aDes,TInt aLength) c*****t; Description Reads specified number of bytes of binary data from file — synchronous overload.2.Typedef TText8 typedef unsigned char TText8;如何取出Symbian手机中的信方法有两个: 1 确定出他们的路径,用文件的方式读; 2 用系统给这两个部分提供的API 通讯录方面的(别人的代码网上找的): _LIT(KNameLabel,”Name”); _LIT(KMobileLabel,”Mobile”); _LIT(KName,”Steve”); _LIT(KMobile,”+8613900000000″);// Open the default contacts database: CContactDatabase* contactsDb = CContactDatabase::OpenL(); CleanupStack::PushL(contactsDb); // Create a contact card and add some fields: CContactItem* contact = CContactCard::NewLC(); CContactItemField* field = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName);field->SetMapping(KUidContactFieldVCardMapUnusedN); field->SetLabelL(KNameLabel); field->TextStorage()->SetTextL(KName); contact->AddFieldL(*field); CleanupStack::Pop(); field = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldPhoneNumber); field->SetMapping(KUidContactFieldVCardMapTEL); field->SetLabelL(KMobileLabel); field->TextStorage()->SetTextL(KMobile); contact->AddFieldL(*field); CleanupStack::Pop();// Add the new contact to the database and set it as the own card: contactsDb->AddNewContactL(*contact); contactsDb->SetOwnCardL(*contact); CleanupStack::PopAndDestroy(2); // contact contactsDb短信的: CMsvEntry或 CMsvServerEntry怎么使用BUTTON 类创建一个 BUTTONS60里面好像没有BUTTON的类吧 1.好像没有必要做BUTTON,触发事件使用MENU就可以了 2.如果非要做的话,可以尝试的下面的简单方法 2.1 使用一个LABEL(设置一下边框属性可以使这个LABEL像一个所谓的BUTTON) 2.2 可以在该LABEL的所处CONTAINER的 OfferKeyEventL(c*****t TKeyEvent& aKeyEvent,TEventCode aType); 处理KEY事件(判断该LABEL拥有FOCUS)图标资源的读取与储存结构可以在AknView类中定义如下的图标数组进行储存图标数据结构,这种结构有图表位图和蒙板(mask)CArrayPtr* iIconArray;具体实现方法: iIconArray->AppendL(CEikonEnv::Static()->CreateIconL(iMbmFile, EMbmFile1, EMbmFile1_mask));在需要贴图标的地方用这个数组句柄引用即可一段左软键菜单的控制代码要求:1点了左软键之后,就相当与点了ok键。2 :把左软键菜单的地方由option改为select// My.rss RESOURCE EIK_APP_INFO { menubar = r_bmpmanip_menubar; // cba = R_AVKON_SOFTKEYS_OPTI*****_EXIT; cba = R_AVKON_SOFTKEYS_SELECT_BACK; // see “epoc32\include\avkon.rsg” }// MyAppUi.cpp void CMyAppUi::HandleCommandL(TInt aCommand) { switch(aCommand) { case EAknSoftkeySelect: // see “epoc32\include\avkon.hrh” { // left softkey is pressed… } … } } }如何在CAknGrid上绘制背景图从CAknGrid派生自己的子类,然后自己draw,如: void CYourGrid:raw(c*****t TRect& aRect) c*****t { CWindowGc& gc = SystemGc(); gc.DrawBitmap(aRect, aYourBitmap); CAknGrid:raw(aRect); } 2007-4-10 08:46 Moving 两种从资源文件中读取常量的方法第一种 是老的方法了 要先 #include 才可以用TBuf<64> buf; CEikonEnv::Static()->ReadResource(buf,R_APP_LABEL); R_APP_LABEL 就是我们在资源文件中定义的常量第二种 新方法 要先 #includeHBufC* buf; buf=StringLoader::LoadLC(R_APP_LABEL);在此之前要求先把资源文件给加进来噢, 格式 #include < 项目名.rsg>如何取得imei#ifndef __WINS__ TPlpVariantMachineId imei; PlpVariant::GetMachineIdL(imei); aImei.Copy(imei); #else如何在Series 60窗体上绘制标签这是一种在Series 60窗体上显示标签的方法。你可以在电量图标或信号图标旁边显示一个标签,为此需要用程序实现。我使用了从CCoeControl继承的CIndicatorIcon 这个类。你需要象这样创建C*****tructL(): void CIndicatorIcon::C*****tructL() { iMyWindowGroup = RWindowGroup(iCoeEnv->WsSession()); User::LeaveIfError(iMyWindowGroup.C*****truct((TUint32)&iMyWindowGroup));iMyWindowGroup.SetOrdinalPosition(0, ECoeWinPriorityAlwaysAtFront); iMyWindowGroup.EnableReceiptOfFocus(EFalse);CreateWindowL(&iMyWindowGroup);// 默认设置指示标签静止 SetIndicatorIconL(EIndicatorIconAppActive);ActivateL(); } 在C*****tructL()中,我调用了另一个函数 SetIndicatorIconL()设置标签: void CIndicatorIcon::SetIndicatorIconL(TIndicatorIcon aIndicatorIconType, TBool aRedraw) { switch(aIndicatorIconType) { case EIndicatorIconEmpty: iIndicator = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_prop_empty); iIndicatorMask = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_prop_empty_mask); break;case EIndicatorIconAppActive: iIndicator = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_bt_connect_on); iIndicatorMask = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_bt_connect_on_mask); break;case EIndicatorIconAppInactive: iIndicator = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_prop_bt_audio); iIndicatorMask = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_prop_bt_audio_mask); break;default: break; }SetRect(TRect(TPoint(KIndicatorPosX, KIndicatorPosY),iIndicator->SizeInPixels()));// 如果 aRedraw == ETrue 从新绘制画布 if(aRedraw) { DrawNow(); } }你需要跳过CCoeControl的Draw()函数代码如下 :void CIndicatorIcon::Draw(c*****t TRect& aRect) c*****t { CWindowGc& gc = SystemGc();gc.Clear(); gc.SetBrushStyle(CGraphicsContext::ENullBrush); gc.BitBltMasked(TPoint(aRect.iTl.iX, aRect.iTl.iY), iIndicator, TRect(TPoint(0, 0), iIndicator->SizeInPixels()), iIndicatorMask, ETrue); } 现在把这些行加入到程序AppUi类的C*****tructL()中:iIndicatorIcon = CIndicatorIcon::NewL(); // 下一行将画标签并绘制到屏幕上 iIndicatorIcon->SetIndicatorIconL(CIndicatorIcon::EIndicatorIconAppInactive, ETrue);判断E盘是否可用TDriveInfo driveInfo; TInt error = fs.Drive(driveInfo, EDriveE); User::LeaveIfError(error); if (driveInfo.iDriveAtt == KDriveAbsent) { // drive E is absent }Reference: “How to retrieve drive and volume information” http://www./developer/techlib/v8.1adocs/doc_source/guide/Base-subsystem-guide/N1007E/FileServerClientSide/FileServerClientSideGuide2/DriveAndVolumeExample.guide.html读取symbian上文件的例子RFile igpFile; RFs fs;TInt aSeek = 0; TInt aFileSize; TBuf16 igpName16;TParse parse ; parse.Set(CEikonEnv::Static()->EikAppUi()->Application()->AppFullName(), NULL, NULL);TBuf16<128> igpFullName ; igpFullName.Copy (parse.DriveAndPath()) ; igpFullName.Append (_L(”dice1.igp”));fs.Connect();// Write to file for later usage igpFile.Open( fs, igpFullName, EFileRead | EFileStream ); igpFile.Seek( ESeekEnd, aSeek );aFileSize = aSeek; aSeek = 0;igpFile.Seek( ESeekStart, aSeek );aFileBuffer = HBufC8::NewL( aFileSize );igpFile.Read( aFileBuffer->Des (), aFileSize );igpFile.Close();fs.Close(); 2007-4-10 08:48 Moving 正确响应FORM的OK和BACK事件TBool CMyForm::OkToExitL ( TInt aButtonId ) { if (aButtonId == EAknSoftkeyOk ) { ….. } else if( aButtonId == EAknSoftkeyBack ) { …… } }流读取windows编写的txt文件// Open file1 _LIT(KMyFile,”c:\\documents\\file1″); RFile myFile; User::LeaveIfError(myFile.Open(fs,KMyFile,EFileShareExclusive|EFileWrite ));// Write to current file position: start of file _LIT8(KWriteBuf,”write data”); myFile.Write(KWriteBuf);// Read from position 0: start of file TBuf8<6> readBuf1; myFile.Read(0,readBuf1); // readBuf1 is now “write ”// Read from current position TBuf8<4> readBuf2; myFile.Read(readBuf2); // readBuf2 is now “data”得到CEikEdwin输入的数据TBuf<128> buf; CEikEdwin* edwin = STATIC_CAST(CEikEdwin*, Control); edwin->GetText(buf);Symbian生成随机数的方法无论开发什么程序,尤其是类似纸牌类游戏和拼图类,以及俄罗斯方块之类的游戏, 随机数发生器是必不可少的。标准c语言里面有seed()和rand()用来生成种子和数值 在symbian平台下面,用什么方法呢?下面就是一个例子TTime theTime( KAknExNoteInitializeTime ); theTime.UniversalTime(); TInt64 randSeed( theTime.Int64() ); // 采用时间初始化随机数种子 TInt number( Math::Rand( randSeed ) % KAknExNoteRandomNumberRange ); // 这里就是调用了 生成的结果放在number中。Symbian中把字符串变成数字的方法我们知道C语言中又很方便的函数,很多种方法可以把字符串变成数字, 比如 char * p = “100″ ; int a; a = atoi(p) ; // 此时a的值就是100了。 或者用这种办法也可以,就是慢点: sscanf(p, “%d”, &a) ; 这样也可以达到同样的效果。但是symbian开发环境中遇到这种情况,我们该怎么做呢? 我们可以考虑采用TLex类,来实现同样的功能。 TBufC buffer = _L(”124″) ; TLex8 lex; TInt value;lex.Assign((c*****t unsigned char*) buffer.Ptr()); if(lex.Val(value) == KErrNone) { // 证明转换没有问题,你可以在value中使用buffer里面的字符串格式的数据了。 } 2007-4-11 08:04 Moving Symbian应用程序中如何备份和载入在S60 3rd中,默认情况下将不被支持。支持备份将使你的应用程序用户界面更加友好,做备份的用户(或者只有一小部分)期望自己的所有应用程序可以被备份。让我们来满足这些用户的需求,大多数情况下,这是非常容易的……使应用程序可以备份文件的另一个原因是Symbian Signed。它不是一个强制的,但是,你的应用程序没有意识到备份的问题,你必须通知Test House 或者他们可能认为你的备份功能失败。再说一次,大多数情况下,备份是非常简单的。程序备份基础如果你想使应用程序具备备份功能,以下是最起码要做到的(也就是说,只能执行和相应的资源文件,没有数据可以被支持): 1. 写一个backup_registration.xml文件,内容如下:CODE:2. 添加它到你的PKG文件CODE: “backup_registration.xml”-”!:\private\\backup_registration.xml”添加私有数据到你的备份文件另外一个常见的需求就是保存数据内容到你的私有文件夹(位置在\private\)。添加以下申明到你的backup_registration.xml 文件中(使用标签):CODE: 你也可以保存所有内容到”nobackup” 私有目录:CODE:你也可以指定些文件代替文件夹:CODE:添加公共文件到备份文件中在前面的内容中,“\”目录被指定为应用程序的私有目录。如何保存那些在私有数据以外的数据呢?这个也很简单,你可以使用另外的一个XML标签。可以用 标签来替换 ,路径相对于你手机的根目录(不需要指定驱动器):CODE: 所知到的Bug不幸的是,包含一些bug会影响备份和重新载入特性:1. 位于C:\System 的数据不被支持:非工作区,除非指定数据到其他位置……2. 使用开发证书(developer certificate),应用程序的备份和载入会失败。这一点是很可怕的:你测应用程序的试备份恢复仅仅只能在你注册了自产生证书(self- generated certificate)的时候。如果你使用开发证书(developer certificate)是不行的,你的应用程序将能够备份,但是恢复的时候会失败。作者不能计算在第二点上到底花费了多少时间,作者说至少花费了一个下午的时间去尝试用开发证书(developer certificate)测试它。Symbian程序中的观察者模式Symbian程序中的观察者模式在这个站点上有很多关于Symbian程序外表的文章,很少有关于架构设计的观点。在以下的文中中,我介绍一下在Symbian应用程序中的观察者模式,我会用一些有意义的类名来代表整个Symbian程序的设计流程。在这个应用程序中,将告诉你在一个Symbian程序中如何使用 Engine和前台,UI接口,和用户直接的交互。在文章中,我已经给了一种解决的方案。在接下来的文章种,我将介绍另外一种方法,通过内嵌类。让我们开始应用程序的引擎类和它的观察者,我们创建了一个观察者接口 MObserver,定义如下: CODE: class MObserver { public: virtual void CallbackFunction1() = 0; }; 接口,它有一个纯虚函数,它必须被一个创建类实现。在我们的例子中,Engine(引擎类)将实现它: CODE: class Engine : public MObserver { public: Engine(CAppUi& aAppUi); void CallbackFunction1();//From MObserver void DoSomething(); Subject& GetSubject(); private: Subject* iSubject; CAppUi& iAppUi; }; 从名字可以清晰的看出,Engine类有一个Subject类,他是实际上在后台工作的类;CAppUi 类是核心与视图的用户接口。引擎创建一个Subject类,通常在Symbian程序中,CAppUi 类是通过veiw类表现数据到用户接口的(UI)。 Subject类申明如下: CODE: class Subject { public: Subject(MObserver& aObserver); void DoSomething(); private: MObserver& iObserver; }; 很明显,Subject类链接了它的观察者iObserver。Symbian程序在一般情况下,在后台通过一些异步函数,Subject类将继承至 CActive类而工作。这里有一个 DoSomething()将调用一些异步函数,这个函数也将调用MObserver中的CallbackFunction1()。 CallbackFunction1 函数将更新AppUi 应用程序或引擎和UI中相关的表现形式。因此让我们来看看CAppUi类的申明: CODE: class CAppUi { public: CAppUi(); Engine& GetEngine(); void PrintToUI(char* msg); virtual ~CAppUi(); private: Engine* iEngine; }; AppUi类的作用是,创建应用程序的引擎。记住,应用程序和Engine已经循环的引用,整个的流程如下: AppUi将创建引擎; Engine创建Subject; AppUi通过一些菜单命令调用Engine中的DoSometing函数; Engine将委派一些任务通过Subject类的DoSometing函数; Subject的DoSometing函数将通知通过CallbackFunction1创建Observer; Subject的DoSometing函数看上去如下: CODE: void Subject::DoSomething() { //Call the Asynchronous function //Now Notify the Observer regarding this. iObserver.CallbackFunction1(); } Observer中的这个回调函数将打印AppUi中消息通过函数PrintToUi。这个函数将呈现从Engine得到的消息到Veiw中。 希望这篇文章能讲清楚一些Symbian入门者对于如何使用UI的疑惑。IMPORT_C关键字释义在Symbian程序中我们经常会看到IMPORT_C这个关键字,它是C:\Symbian\8.0a\S60_2nd_FP2_SC\epoc32\include下e32def.h文件里面定义的一个宏. 原定义如下:#define IMPORT_C __declspec(dllexport)那么__declspec(dllexport)又是什么东东呢?先看代码:以下是在dev-c++里建立自已的dll时的dll.h里面的代码,这里面有一个_declspec(dllexport)#ifndef _DLL_H_ #define _DLL_H_ //防重复定义#if BUILDING_DLL # define DLLIMPORT __declspec (dllexport) #else /* Not BUILDING_DLL */ # define DLLIMPORT __declspec (dllimport) #endif /* Not BUILDING_DLL */DLLIMPORT void HelloWorld (void);#endif /* _DLL_H_ */上面代码里面的_delcspce(dllexport)被定义为宏,这样可以提高程序的可读性!这个的作用是将函数定义为导出函数,也就是说这个函数要被包含这个函数的程序之外的程序调用!本语句中就是:void Helloword(void)摘自msdn:在 32 位编译器版本中,可以使用 __declspec(dllexport) 关键字从 DLL 导出数据、函数、类或类成员函数。__declspec(dllexport) 将导出指令添加到对象文件若要导出函数,__declspec(dllexport) 关键字必须出现在调用约定关键字的左边(如果指定了关键字)。例如:__declspec(dllexport) void __cdecl Function1(void); 若要导出类中的所有公共数据成员和成员函数,关键字必须出现在类名的左边,如下所示:class __declspec(dllexport) CExampleExport : public CObject{ … class definition … }; 生成 DLL 时,通常创建一个包含正在导出的函数原型和/或类的头文件,并将 __declspec(dllexport) 添加到头文件中的声明。若要提高代码的可读性,请为 __declspec(dllexport) 定义一个宏并对正在导出的每个符号使用该宏:#define DllExport __declspec( dllexport ) __declspec(dllexport) 将函数名存储在 DLL 的导出表中。 2007-4-11 08:08 Moving 如何让程序支持皮肤功能 |
|
|
|