導航:首頁 > 新媒體 > c中封裝的信息流

c中封裝的信息流

發布時間:2021-03-21 07:35:15

1、怎樣將一個C程序封裝起來?

首先,發布一個可執行程序,在生成exe的時候,選擇release編譯。
然後,在VC中啟動的時候,輸出欄會顯示一系列這個exe所載入的dll或其他插件,將那些dll和插件(系統的除外)與生成的exe放在一起,然後就可以發布了。
我說的只是大概流程,中間一些細節自己體會吧。

2、如何用C語言封裝 C++的類,在 C裡面使用

C一般不能直接調用C++函數庫,需要將C++庫封裝成C介面後,才可以使用C調用。
下面舉例,說明一個封裝策略:

//code in add.cxx
#include "add.h"
int sample::method()
{
cout<<"method is called!\n";
}
//code in add.h
#include
using namespace std;
class sample
{
public:
int method();
};
將上面的兩個文件生成動態庫libadd.so放到 /usr/lib目錄下,編譯命令如下:
sudo g++ -fpic -shared -g -o /usr/lib/libadd.so add.cxx -I ./
由於在C中不能識別類,所以要將上面類的成員函數,要封裝成C介面函數才能被調用。下面進行封裝,將輸出介面轉換成C介面。
//code in mylib.cxx
#include "add.h"
#ifndef _cplusplus
#define _cplusplus
#include "mylib.h"
#endif

int myfunc()
{
sample ss;
ss.method();
return 0;
}
//code in mylib.h
#ifdef _cplusplus
extern "C"
{
#endif

int myfunc();

#ifdef _cplusplus
}
#endif
在linux下,gcc編譯器並沒用變數_cplusplus來區分是C代碼還是C++ 代碼(沒有宏定義),如果使用gcc編譯器,這里我們可以自己定義一個變數_cplusplus用於區分C和C++代碼,所以在mylib.cxx中定義 了一個變數_cplusplus用於識別是否需要「extern "C"」將函數介面封裝成C介面。但是如果使用g++編譯器則不需要專門定義_cplusplus,編譯命令如下:
g++ -fpic -shared -g -o mylib.so mylib.cxx -la -I ./
main.c
#include

#include
#include "mylib.h"

int
main()
{
int (*dlfunc)();
void *handle; //定義一個句柄
handle = dlopen("./mylib.so", RTLD_LAZY);//獲得庫句柄
dlfunc = dlsym(handle, "myfunc"); //獲得函數入口
(*dlfunc)();
dlclose(handle);

return 0;
}
編譯命令如下:
gcc -o main main.c ./mylib.so -ldl
下面就可以執行了。
需要說明的是,由於main.c 和 mylib.cxx都需要包含mylib.h,並且要將函數myfunc封裝成C介面函數輸出需要「extern "C"」,而C又不識別「extern "C"」,所以需要定義_cplusplus來區別處理mylib.h中的函數myfunc。
在main.c的main函數中直接調用myfunc()函數也能執行,這里介紹的是常規調用庫函數的方法。

3、mfc中cview類有什麼作用?

cview類是負責每個軟體系統向顯示器輸出各種信息流以及控制處理的類,但是它不負責物理層的輸出操作,因為windows是一個具有與設備無關性的操作系統,cview類同過相應一系列傳送給他的一些列消息,通過自已的一系列函數與之相映射,然後將消息傳送給專門用來描述輸出設備的CDC對象來完成顯示信息的。。。

具體的封裝函數太多了介紹幾個重要的,具體的可以去查msdn。

關聯文檔對象視圖需要表示文檔數據,所以文檔對象與視圖對象必須建立關聯。這樣,當文檔數據發生變化時,它可以及時通知視圖;當視圖需要顯示不同的文檔數據時,它可以從文檔對象中提取。

在文檔/視圖框架程序中,文檔對象總是在視圖之前建立,而在視圖的WM_CREATE消息處理函數中,建立了它與文檔對象的關聯。代碼如下:

Int CView::OnCreate (LPCREATESTRUCT lpcs)

{

if (CWnd::OnCreate(lpcs) == -1)

return -1;

// m_pDocuemnt視圖成員,用於存儲相應文檔對象的指針,此時為空

ASSERT(m_pDocument == NULL);

CCreateContext* pContext = (CCreateContext*)lpcs->lpCreateParams;

// pContext->m_pCurrentDoc是已經建立的文檔對象的指針

if (pContext != NULL && pContext->m_pCurrentDoc != NULL)

{

// 將當前視圖加入文檔對象的視圖列表中,因為一個文檔可關聯多個視圖

pContext->m_pCurrentDoc->AddView(this);

/* 在文檔的AddView()函數中,已經將當前文檔對象指針賦給m_pDocument視圖成員。這樣,在視圖建立之初,二者就建立了關聯。*/

ASSERT(m_pDocument != NULL);

}

else

{

TRACE(「Warning: Creating a pane with no CDocument.\n」);

}

return 0; // ok

}

同時,視圖類定義了成員函數GetDocument(),返迴文檔對象的指針。代碼如下:

CDocument* CView::GetDocument() const

{

ASSERT(this != NULL);

return m_pDocument;

}

視圖總是在文檔對象之前銷毀,在視圖的析構函數中,與文檔對象解除關聯。代碼如下:

CView::~CView()

{

if (m_pDocument != NULL)

m_pDocument->RemoveView(this);

}

編輯本段視圖的繪制窗口的繪制工作總是在WM_PAINT消息處理中進行的,當窗口需要繪制時,它會收到系統發來的WM_PAINT消息。在繪制過程中,首先要准備顯示設備句柄,最後要釋放句柄。眾所周知,在視圖窗口中繪制,無需重載WM_PAINT消息處理函數OnPaint(),因為有一個更加友好的繪制新口:OnDraw()。該函數的實參是一個已經准備好的顯示設備,最後無需釋放。其實,這一切還是WM_PAINT消息處理函數OnPaint()為我們准備的,代碼如下:

void CView::OnPaint()

{

// CPaintDC類維護顯示設備

CPaintDC dc(this);

OnPrepareDC(&dc);

OnDraw(&dc);

}

OnPrepareDC()是一個虛擬函數,它總是在OnDraw()之前執行,可以重載它,設置繪圖模式。因為OnDraw()每次執行,都使用不同的CPaintDC對象,所以本次繪圖模式的狀態不能保留到下一次。

OnDraw()在視圖基類CView中定義為純虛函數。例如:

virtual void OnDraw(CDC* pDC) = 0;

所以CView是抽象基類,不能實例化,而派生類必須重載OnDraw()。

編輯本段虛函數 OnUpdate當文檔數據發生變化時,文檔對象調用CDocument::UpdateAllView()通知所有視圖,作為響應,視圖的OnUpdate()成員被調用。所以,重載的OnUpdate()應該能夠根據需要,將文檔數據的變化反映在視圖中。CView::OnUpdate()只是簡單地使客戶區無效,導致客戶區重畫。例如:

void CView::OnUpdate(CView* pSender, LPARAM, CObject*)

{

ASSERT(pSender != this);

UNUSED(pSender); // unused in release builds

Invalidate(TRUE);

}

編輯本段虛函數 OnInitialUpdate()在初始創建、調用OnCreate()之後,或者在File/New、File/Open命令後被框架調用。基類CView::OnInitialUpdate()只是簡單地調用OnUpdate(),可以重載它完成初始化工作。但注意,它可能被多次調用。

void CView::OnInitialUpdate()

{

OnUpdate(NULL, 0, NULL);

}

編輯本段虛函數 CalcWindowRect每當主框架窗口的客戶區尺寸發生變化或控制條的位置發生變化,需要重新排列客戶區時,調用該函數,根據視圖客戶區尺寸計算視圖窗口的尺寸。

我們知道,排列主窗口客戶區是由CFrameWnd::RecalcLayout()完成的。顯然,視圖的CalcWindowRect()函數也是由它觸發調用的。主窗口的客戶區尺寸減掉所有控制佔用的部分,剩下的區域分給視圖,這部分區域作為實參傳入CalcWindowRect()。在CalcWindowRect()函數內,需要計算視圖窗口的尺寸。代碼如下:

void CView::CalcWindowRect(LPRECT lpClientRect, UNIT nAdjustType)

{

// lpClientRect此時是整個視圖客戶區的尺寸

// 需要為滾動條增加尺寸嗎

if (nAdjustType != 0)

{

// 調用API,根據窗口風格計算窗口尺寸

::AdjustWindowRectEx(lpClientRect, 0, FALSE, GetExStyle());

DWORD dwStyle = GetStyle();

if (dwStyle & WS_VSCROLL)

{

// 為垂直滾動條增加尺寸

int nAdjust = afxData.csVScroll;

if (dwStyle & WS_BORDER)

nAdjust -= CX_BORDER;

lpClientRect->right += nAdjust;

}

if (dwStyle & WS_HSCROLL)

{

// 為水平滾動條增加尺寸

int nAdjust = afxData.cyHScroll;

if (dwStyle & WS_BORDER)

nAdjust -= CY_BORDER;

lpClientRect->bottom += nAdjust;

}

return;

}

// 無需為滾動條增加尺寸,調用基類成員完成計算

CWnd::CalcWindowRect(lpClientRect, nAdjustType);

}

編輯本段虛函數PostNcDestroy在視圖窗口關閉時最後調用的成員函數,它與CFrameWnd::PostNcDestroy完成相同的功能,即刪除視圖對象。代碼如下:

void CView::PostNcDestroy()

{

delete this;

}

這樣,可以不必關心視圖的釋放工作,即使它在堆中構造。

編輯本段虛函數OnCmdMsg在討論CFrameWnd::OnCmdMsg()時已經了解過該函數,下面只給出它的代碼:

BOOL CView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)

{

// 首先查找自身的命令消息映射

if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))

return TRUE;

// 如果視圖本身沒有處理該命令,將機會留給與其關聯的文檔對象

if (m_pDocument != NULL)

{

CPushRoutingView push(this);

return m_pDocument->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

}

return FALSE;

}

編輯本段虛函數 OnActivateView當視圖被激活為活動視圖,或由活動轉為非活動時,調用該函數通知視圖。基類的實現只是設置該視圖為焦點。代碼如下:

void CView::OnActivateView(BOOL bActivate, CView* pActivateView, CView*)

{

UNUSED(pActivateView); // unused in release builds

if (bActivate) // 當前狀態為活動嗎

{

ASSERT(pActivateView == this);

// 如果其父窗口也是活動的,則設置焦點。(在MDI中,其父框架可能是非活動的)

if (IsTopParentActive())

SetFocus();

}

}

4、C++中什麼是封裝?類是如何進行封裝的?

新建類庫項目,建立自己的類XXX.cs在開始菜單找到 Visual Studio 2005---->Visual Studio Tools------> Visual Studio 2005命令提示輸入以下命令:csc /t:library /out:c:\XXX.dll c:\XXX.cs其中c:\XXX.cs 為要生成的cs文件;c:\XXX.dll為生成的dll文件

5、c語言中可封裝指啥

結構體,利用在每個函數中傳一個結構體,結構體定義為全部變數,可以實現C版得繼承和封裝,但不能實現多態;

6、c ++中的封裝和java中的封裝的區別是什麼。。。知道的請詳細說說,謝謝

沒區別吧,都是面向對象的封裝思想

7、關於C語言中封裝函數的問題

回刪是這回事:
\b是退格鍵,退格加輸入,就是回刪了。
例如:
cout << "Enter three characters:___\b\b\b";
char ch[4];//最多輸入三個字元,多了就越界了
cin>>ch;
cout<<ch<<endl;
//......
自己在編譯器里試一試就知道了。

8、c語言中要封裝一個函數( 比如什麼printf之類的),肯定得用.c和.h文件,函數聲明在.h文件中.函數實現在c文

//mvector.h -- 聲明
#ifndef MVECTOR_H_
#define MVECTOR_H_  
typedef struct _mvect
{
int x;
int y;
}vect;
void getvect(vect* v);//聲明
void showvect(vect v);//聲明
#endif//mvector.c -- 實現
#include "mvector.h"
#include <stdio.h> 
void getvect(vect* v)
{
scanf("%d,%d",&(v->x),&(v->y));  
 }  
void showvect(vect v)
{
printf("%d,%d",v.x,v.y);  
 }//main.c -- 使用
#include "mvector.h"
#include <stdio.h>
int main()
{
vect a;
getvect(&a);
showvect(a);
}

注意mvector.h必須位於當前文件夾下,且必須把mvector.c和main.c放在一個工程里編譯。

輸入:2,3

輸出:2,3

9、c語言的封裝

就是定義一個類,然後把它放在一個新建的文件下下面,封裝起來,,要用的時候,直接調用出來,使得代碼更簡潔,更易懂。

10、在C語言怎樣對數據和操作的封裝

以下僅為個人理解:

數據封裝就是使用類似結構體的形式,將多個相關數據合並到一個結構體中,在程序中作為一個整體進行付值和調用操作。

操作封裝就是對多個重復使用且具有相同功能的語句進行整合,打包成一個實現固定功能的函數。

與c中封裝的信息流相關的知識