导航:首页 > 新媒体 > 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中封装的信息流相关的知识