、(C 基于Internet (企業(yè)內(nèi)部網(wǎng))的網(wǎng)絡(luò)電)
態(tài)性翻譯成中文是多型(態(tài))
這是一個(gè)對(duì)象指向語言中的基本概念,就是變量(class、struct)在運(yùn)行時(shí)去改變行為而不是編譯時(shí)決定。
C 語言言很難做到這一點(diǎn),用函數(shù)指針抽換可以勉強(qiáng)做到,但這樣的努力容易使人進(jìn)步,換來的好辦法又有限,最大的缺口是超級(jí)難用??蛻舳吮仨氈澜裉煲樯趺春瘮?shù)指針,光這一點(diǎn)就已經(jīng)過離物件導(dǎo)向的封裝概念了。
今天要介紹一種能夠完全封裝且實(shí)用多種的機(jī)制,不多說,先來看看客戶端的代碼
int main(int argc, char **argv)
{
struct dl_module *module=NULL;
int value=0;
printf("get %s's price: ", argv[1]);
module=module_open(argv[1]);
value=(*module->get_price)();
printf("%d\n", value);
module_close(module);
return 0;
}
struct dl_module這是我的多模接口,與多種對(duì)象導(dǎo)向一樣,這是多模的必要條件,當(dāng)用戶從shell腳本中輸入不同的參數(shù),程序必須動(dòng)態(tài)的吐出價(jià)格。
這邊只有定義為一個(gè)類型,并且能夠做到運(yùn)行時(shí)改變值的能力,這就是多功能的典型特征。
因?yàn)镃語言沒有構(gòu)造式和解構(gòu)式,所以客戶端只好傻傻的調(diào)用module_open,module_close并且,自動(dòng)化的構(gòu)造式和解構(gòu)式容我有機(jī)會(huì)再介紹吧。
接下來看看神奇的模塊相關(guān)API
struct dl_module
{
void *handle;
int (*get_price)(void);
};
struct dl_module *module_open(char *name)
{
char path[100];
void *handle=NULL;
struct dl_module *module=malloc(sizeof(struct dl_module));
sprintf(path, "lib%s.so", name);
handle=dlopen(path, RTLD_NOW);
module->get_price=(int (*)(void))dlsym(handle, "get_price");
module->handle=handle;
return module;
}
void module_close(struct dl_module *module)
{
dlclose(module->handle);
free(module);
}
透過dlopen和dlsym,這就允許程序在運(yùn)行時(shí)以動(dòng)態(tài)方式載入共享庫(kù)或動(dòng)態(tài)庫(kù),而外部的shell只需要把.so準(zhǔn)備好即可。
gcc poly_test.c -ldl
gcc -fPIC cola.c -shared -o libcola.so
LD_LIBRARY_PATH=./ ./a.out cola獲取可樂的價(jià)格:29
例子中的cola可以換成各種東西,例如sunflower或banana,只是記得要實(shí)踐libsunflower.so。
至於cola.c里面其實(shí)現(xiàn)就只有一個(gè)函數(shù):get_price,而且很單純的return 29(反正量簡(jiǎn)單比較好懂)
這種做法就將不同的實(shí)施方案封裝在共享庫(kù)中,而客戶端可以透過string去抽換功能,甚至更糟的是,連函數(shù)名都用string去抽換也行。
這些示例代碼都沒做error handle,要抄的人記得自己加(不然很容易SIGSEGV)
這種作法是把編譯時(shí)可以抓到的bug推遲到運(yùn)行時(shí)去,如果你寫下來get_price形成get_prince,這個(gè)支程就掰了。
配套就是寫一個(gè)parser去建立symbol的綜合表并且去檢查所有的module_open是不是符合綜合表的內(nèi)部?jī)?nèi)容,然后之后在Makefile內(nèi)部調(diào)用這個(gè)parser做preprocess,如此即可完整其美,又有好的程序結(jié)構(gòu)又能兼顧編譯時(shí)bug。
轉(zhuǎn)自:https://wirelessr.gitbooks.io/working-life/content/polymorphism_in_c.html
使用QJSEngine引擎編譯和運(yùn)行JavaScript腳本時(shí),你可以將JavaScript代碼保存在一個(gè)獨(dú)立的文件中,并使用QFile讀取該文件內(nèi)容,然后使用QJSEngine的evaluate()方法執(zhí)行該代碼。下面是一個(gè)示例,演示如何加載并執(zhí)行一個(gè)獨(dú)立的JavaScript文件:
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QJSEngine>
#include <QJSValue>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 讀取JavaScript文件內(nèi)容
QFile file("script.js");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Failed to open script file!";
return -1;
}
QString script=file.readAll();
file.close();
QJSEngine engine;
// 執(zhí)行JavaScript腳本
QJSValue result=engine.evaluate(script);
// 檢查結(jié)果并輸出
if (result.isNumber()) {
int sum=result.toInt();
qDebug() << "Sum: " << sum;
} else {
qDebug() << "Error evaluating script!";
}
return a.exec();
}
在上面的示例中,我們首先使用QFile打開并讀取名為"script.js"的JavaScript文件的內(nèi)容。然后,我們創(chuàng)建了一個(gè)QJSEngine對(duì)象,并使用evaluate()方法執(zhí)行從文件中讀取的JavaScript代碼。最后,我們檢查結(jié)果的類型并輸出。
確保將實(shí)際的JavaScript文件命名為"script.js"并與可執(zhí)行文件位于同一目錄下。你可以在JavaScript文件中編寫復(fù)雜的功能,包括定義函數(shù)、使用對(duì)象等。
這是一個(gè)簡(jiǎn)單的示例,演示了如何使用QJSEngine引擎加載和執(zhí)行一個(gè)獨(dú)立的JavaScript文件
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。