當前位置:首頁 » 編程語言 » c語言代碼如何封裝
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言代碼如何封裝

發布時間: 2022-12-17 01:29:25

① 如何封裝c語言程序

安裝vc6.0,初學者安裝6.0的,寫一個windows窗口應用程序,編譯後就跟你運行360或者其他軟體一樣,會出現個窗口界面,或者有音效或者彈出窗口,這些需要封裝代碼的。

② 如何用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()函數也能執行,這里介紹的是常規調用庫函數的方法。

③ c語言的封裝

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

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

以下僅為個人理解:

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

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

⑤ 如何將c程序封裝為DLL

http://icese.net/read.php?tid=7181
http://icese.net/read.php?tid=7180

用VC編寫DLL教程

用Visual Sudio 6.0新建一個工程,工程的類型選擇Win32 Dynamic-Link Library.工程名任意,其他所有選項取默認
新建一個cpp文件,代碼如下:

int add(int a ,int b){
return a+b;
}

如果工程類型是Win32 Console Application,那麼在編譯鏈接以後,會產生一個Debug目錄,並且裡面有一個exe文件
這里我們的工程類型是Win32 Dynamic-Link Library,在編譯鏈接以後,我們期望產生一個Debug目錄,並且裡面有一個dll文件
事實正是如此
我們可以用depends工具打開這個dll文件以查看它導出了什麼函數
depends工具在Tools菜單下.實際上它是D:\Program Files\Microsoft Visual Studio\Common\Tools下的一個文件
我們發現,這個dll沒有導出任何東西
這是因為我們並沒有說明我們要導出的東西.在那個cpp里的函數並不是默認會被導出的.因為它們可能只是被我們要導出的函數的調用的"內部函數".
要導出一個函數,我們須要加上_declspec(dllexport),代碼變為:

int _declspec(dllexport) add(int a ,int b){
return a+b;
}

再鏈接一次
再查看該dll文件,發現有一個?add@@YAHHH@Z的函數.好像很怪,不過總算看到東西了
現在來測試一下這個dll
新建一個工程,類型選Win32 Console Application
新建一個cpp文件,代碼如下

#include <iostream.h>
#include <Windows.h>
void main(){
typedef int (*ADD)(int ,int);//函數指針類型
HINSTANCE Hint = ::LoadLibrary("DLL.dll");//載入我們剛才生成的dll
ADD add = (ADD)GetProcAddress(Hint,"add");//取得dll導出的add方法
cout<<add(3,4)<<endl;
}

其中LoadLibrary都是Windows.h裡面聲明了的函數
編譯鏈接,都沒問題
運行.出錯了!
分析一下,程序怎麼知道去哪裡找我們的dll呢?
它會按如下順序搜索:當前可執行模塊所在的目錄,當前目錄, Windows 系統目錄,Windows 目錄。GetWindowsDirectory 函數檢索此目錄的路徑,PATH 環境變數中列出的目錄。
所以我們要把我們的dll復制一份到這個測試工程的Debug目錄之後,再運行
還是出錯了!
分析一下.我們剛才看到的是一個叫?add@@YAHHH@Z函數.那麼,是不是這個原因呢?
把代碼改為:

#include <iostream.h>
#include <Windows.h>
void main(){
typedef int (*ADD)(int ,int);//函數指針類型
HINSTANCE Hint = ::LoadLibrary("DLL.dll");//載入我們剛才生成的dll
ADD add = (ADD)GetProcAddress(Hint,"?add@@YAHHH@Z");//取得dll導出的add方法
cout<<add(3,4)<<endl;
}

再編譯鏈接,運行,成功了!
那麼怎麼可以正確導出我們函數的名字呢?
在生成dll的工程的代碼加上extern "C",改為:

extern "C" int _declspec(dllexport) add(int a ,int b)...{
return a+b;
}

編譯鏈接後,查看dll文件,可以看到導出的函數變為add了
這時下面代碼可以正常工作了

#include <iostream.h>
#include <Windows.h>
void main()...{
typedef int (*ADD)(int ,int);//函數指針類型
HINSTANCE Hint = ::LoadLibrary("DLL.dll");//載入我們剛才生成的dll
ADD add = (ADD)GetProcAddress(Hint,"add");//取得dll導出的add方法
cout<<add(3,4)<<endl;
}

除了用_declspec(dllexport)指明要導出的函數,用extern "C"來糾正名字,我們還可用一個.def文件來達到以上目的
在dll工程里新建一個文件,類型選Text File,在名字要帶上後綴.def
內容如下:
LIBRARY
EXPORTS
add
剩下的步驟就和之前一樣了
用def文件還可以改變導出的函數的名字,例如
LIBRARY
EXPORTS
myadd = add
使得導出的函數叫myadd,而不是add
還可以給函數指定一個序號
如:
LIBRARY
EXPORTS
myadd=add @4
給myadd指定了一個序號
在測試工程里,可以根據序號取得我們的函數:

#include <iostream.h>
#include <Windows.h>
void main(){
typedef int (*ADD)(int,int);
HINSTANCE hInstance=::LoadLibrary("DLL.dll");
ADD add=(ADD)GetProcAddress(hInstance,MAKEINTRESOURCE(4));//根據序號取得函數
cout<<add(3,4)<<endl;
add=(ADD)GetProcAddress(hInstance,"myadd");//在def文件里指定的名字
cout<<add(3,4)<<endl;
FreeLibrary(hInstance);//釋放載入了的dll文件占的資源
}

以上講的是運行時動態載入dll,下面講啟動時動態載入dll

產生dll的工程不用變,還是上面這個(名字是myadd,序號為4)
測試代碼改為:
//先把DLL.lib文件復制到本工程目錄里

#include <iostream.h>
#pragma comment(lib,"DLL.lib")
extern int myadd(int ,int );//沒有加這句而只加上面這句(或在工程設置里加上DLL.lib)會鏈接錯誤
void main()
{
cout<<myadd(3,4)<<endl;
}

這種方法調用dll,在鏈接的時候,會在我們exe里包含要引用的符號,在啟動程序的時候就會載入所有需要的dll.(之前說錯了,說這是靜態鏈接)
#pragma comment(lib,"DLL.lib")指明了用到哪個dll,其中DLL.lib可以在Debug找到.我們也要把DLL.lib復制到測試工程目錄(不是Debug目錄).我們也可以在工程屬性里添加.方法是Project--Settings--Link,在Object/libraries Moles最後加上 DLL.lib
extern int add(int ,int );指明了我們的add是一個外部函數,而不是在本文件定義的

最後,強調一下,要把該復制的文件復制到正確的地方.
當你產生的dll文件和我說的不一致時,試一下選Build-Rebuild All

⑥ C語言中如何將自己常用的函數封裝到編譯器的庫函數中具體應該怎麼做呢

用編譯器提供的庫管理工具。
C語言的編譯器都會提供一個命令行工具,可以把自己編譯後的.obj模塊加入指定的庫文件,以後使用時只需要連接該庫文件即可。這個命令行工具通常是lib.exe,用這個工具可以查看庫中的模塊,可以把模塊加入到庫中,可以從庫中刪除模塊。這個工具不僅僅是自己建立的庫文件的管理工具,可以管理所有的庫文件,包括C語言提供的標准庫。

⑦ c語言如何封裝一個帶有可變參數的方法

需要借用C語言的VA_LIST宏定義,及相關操作來實現可變參數。

VA_LIST所在頭文件:#include <stdarg.h>,用法如下:

(1)首先在函數里定義一具VA_LIST型的變數,這個變數是指向參數的指針;

(2)然後用VA_START宏初始化剛定義的VA_LIST變數;

(3)然後用VA_ARG返回可變的參數,VA_ARG的第二個參數是你要返回的參數的類型(如果函數有多個可變參數的,依次調用VA_ARG獲取各個參數);

(4)最後用VA_END宏結束可變參數的獲取。

以下是一個自定義列印介面的實現:

intmy_printf(constchar*fmt,...)//...表示參數可變
{
va_listargs;//定義va_list
staticchargc_PrintfOutBuff[1000];
va_start(args,fmt);//初始化
vsnprintf((char*)gc_PrintfOutBuff,1000,(char*)fmt,args);//這里沒有使用VA_ARG取回單個變數,而是借用vsnprinf一次性讀取。
va_end(args);//結束獲取
puts("%s",(constchar*)gc_PrintfOutBuff);//使用。
return0;
}