现在的位置: 首页 > 综合 > 正文

ubuntu下codeblocks起步(补充篇)-下

2013年12月10日 ⁄ 综合 ⁄ 共 4804字 ⁄ 字号 评论关闭

CodeBlocks学习 如何编译多个目标  

呵,说多个目标,还不如说是如何在一个工程中,编译不同的动态库。想想MFC中一个动态库就是一个工程,当动态库多的时候,觉得管理不是很好,CodeBlocks支持在一个工程中,可以编译多个动态库,以下是我的学习体会。

之所以会有这样的需求,主要是因为我在用了ECLIPSE之后,觉得其plugin功能真的很强大,再者,CodeBlocks也是基于plugin框架架构的,所以想具体的学习一下,基于wxWidgets的plugin程序框架设计。

在学习过程中,我发现,一个工程一个库,这个管理不太方便。于是,就想可不可以在同一个工程中,编译不同的目标动态库?经过一番摸索,CodeBlocks可以实现我的需求。以下将方法记录下来,以备查阅。

  1.  创建一个wxStudy工程,增加4个文件到工程, 
//MainApp.h
#ifndef WX_MAIN_APP_H
#define WX_MAIN_APP_H

#include 
<wx/app.h>

class MainApp : public wxApp
{

    
public:
        MainApp();
    
public:
        
virtual bool OnInit();

    
private:
        
void InitFrame();

}
;

DECLARE_APP(MainApp)
#endif

 

//MainApp.cpp


#include 
"mainApp.h"

#include 
"MainFrame.h"


IMPLEMENT_APP(MainApp)


MainApp::MainApp()
{
}


bool MainApp::OnInit()
{
    InitFrame();
    
return true;
}


void MainApp::InitFrame()
{
    MainFrame
* pMainFrm = new MainFrame(_T("MainFrame"));
    pMainFrm
->Show(true);
}

 

//MainFrame.h

#ifndef MAIN_FRAME_H
#define MAIN_FRAME_H

#include 
<wx/frame.h>
//#include <wx/wx.h>

class MainFrame : public wxFrame
{
    
public:
        MainFrame(
const wxString& strTitle);

    
private:
        
void InitCtrl();

    
private://event
        void OnAbout(wxCommandEvent& event);
        
void OnQuit(wxCommandEvent& event);

        
//测试动态库
        void OnShowMessage(wxCommandEvent& event);
    
private:
        DECLARE_EVENT_TABLE()
}
;
#endif

 

//MainFrame.cpp

#include 
"MainFrame.h"

#include 
<wx/menu.h>
//#include <wx/string.h>
#include <wx/msgdlg.h>
#include 
<wx/dynlib.h>
#include 
<wx/filefn.h>
#include 
<wx/filename.h>

#include 
"maindef.h"
//EVENT DECLARE
BEGIN_EVENT_TABLE(MainFrame,wxFrame)

    EVT_MENU(wxID_EXIT,MainFrame::OnQuit)
    EVT_MENU(wxID_ABOUT,MainFrame::OnAbout)
    EVT_MENU(wxID_TEST_DLL,MainFrame::OnShowMessage)
END_EVENT_TABLE()

//END EVENT DECLARE

MainFrame::MainFrame(
const wxString& strTitle)
:wxFrame(NULL,wxID_ANY,strTitle)
{
    InitCtrl();
}



void MainFrame::InitCtrl()
{

    wxMenu
* pMenu = new wxMenu();
    pMenu
->Append(wxID_EXIT,_T("Exit"));
    pMenu
->Append(wxID_ABOUT,_T("About"));
    pMenu
->Append(wxID_TEST_DLL,_T("测试动态库"));

    wxMenuBar
* pMenuBar = new wxMenuBar();
    pMenuBar
->Append(pMenu,_T("File"));


    SetMenuBar(pMenuBar);

}


/*
*   退出程序
*   @param wxCommandEvent& event
*/

void MainFrame::OnQuit(wxCommandEvent& event)
{
    Close();
}


void MainFrame::OnAbout(wxCommandEvent& event)
{

    wxString strMsg(_T(
"wxWidgets study."));
    wxString strCaption(_T(
"关于"));
    wxMessageBox(strMsg, strCaption, wxOK 
| wxICON_INFORMATION,this);


    
//wxMessageBox("Quit program?", "Confirm",wxYES_NO | wxCANCEL, this);

}


void MainFrame::OnShowMessage(wxCommandEvent& event)
{

    
//wxString dir(wxGetWorkingDirectory());
    
//wxMessageBox(dir,_T("dir"),wxOK);

    wxChar name[MAX_PATH] 
= {0};
    GetModuleFileName(
0L, name, MAX_PATH);
    
//wxMessageBox(name,_T("dir"),wxOK);
    wxFileName fname(name);
    wxString strPath(fname.GetPath(wxPATH_GET_VOLUME));
    wxDynamicLibrary lib;
    wxString libfile(strPath 
<< _T("/plugins/msgplugin/msgplugin.dll"));
    lib.Load(libfile);
    
if(!lib.IsLoaded())
    
{
        wxMessageBox(libfile 
<< _T(" load error."),_T("Error"),wxOK | wxICON_ERROR);
        
return;
    }



    typedef 
int (*ShowMessageProc)(const wxString&);

    ShowMessageProc ShowMessage 
= (ShowMessageProc)lib.GetSymbol(_T("ShowMessage"));
    
if(NULL == ShowMessage)
    
{
        wxMessageBox(_T(
"don't call the method: ShowMessag"), _T("Error"),
            wxOK 
| wxICON_ERROR);
        
return;
    }


    ShowMessage(_T(
"call from "+ libfile);
}

 2.创建动态库所需要的文件src/plugins/msgplugin/msh.h;src/plugins/msgplugin/msh.cpp 

//msg.h

#ifndef MSG_H_INCLUDED
#define MSG_H_INCLUDED

#include 
"../pluginset.h"
#include 
<wx/string.h>

BEGIN_EXPORT_LANGUAGE()

int PLUGIN_EXPORT ShowMessage(const wxString& msg);

END_EXPORT_LANGUAGE()
#endif // MSG_H_INCLUDED

 

//msg.cpp

#include 
"msg.h"
#include 
<wx/msgdlg.h>

int ShowMessage(const wxString& msg)
{
    wxMessageBox(msg,_T(
"msg"));
    
return 0;
}

3.设置编译目标 ,File->new -> build target...,如下图所示:

选择 Dynamic Link library,编译动态库,点GO,next,如下图:

输入msgplugin后,点Finish,这样我们就创建了一个编译目标,但这还不够,因为,还没有为此目标增加任何的源文件,接下来,增加源文件。

 在工程树上点右键,选择Properties->Build targets选项卡,如下图,你会看到我们输入的编译目标(debug_msgplugin):

在build target files中,选择我们的源文件,如下图:

呵,离成功还差一步了,接下来,我们要做的就是定义__declspec(__dllexport)或是__dllimport,为什么了,在工程中,我们增加一个pluginset.h的文件,文件内容如下:

//pluginset.h

#ifndef PLUGINSET_H
#define PLUGINSET_H

//windows平台下,动态库的前辍定义
#ifdef __WXMSW__
    #ifndef PLUGIN_EXPORT
        #ifdef EXPORT_LIB
            
#define PLUGIN_EXPORT __declspec(__dllexport)
        
#else // !EXPORT_LIB
            
#if BUILDING_PLUGIN
                
#define PLUGIN_EXPORT __declspec(__dllexport)
            
#else // !BUILDING_PLUGIN
                
#define PLUGIN_EXPORT __declspec(__dllimport)
            
#endif // BUILDING_PULGIN
        
#endif // EXPORT_LIB
    
#endif // PLUGIN_EXPORT
#else
    
#define PLUGIN_EXPORT
#endif

//导出方式是c方式还是c++方式

#ifdef PLUGIN_EXPORT_C

抱歉!评论已关闭.