Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
、(C 基于Internet (企業內部網)的網絡電)
態性翻譯成中文是多型(態)
這是一個對象指向語言中的基本概念,就是變量(class、struct)在運行時去改變行為而不是編譯時決定。
C 語言言很難做到這一點,用函數指針抽換可以勉強做到,但這樣的努力容易使人進步,換來的好辦法又有限,最大的缺口是超級難用。客戶端必須知道今天要抽甚么函數指針,光這一點就已經過離物件導向的封裝概念了。
今天要介紹一種能夠完全封裝且實用多種的機制,不多說,先來看看客戶端的代碼
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這是我的多模接口,與多種對象導向一樣,這是多模的必要條件,當用戶從shell腳本中輸入不同的參數,程序必須動態的吐出價格。
這邊只有定義為一個類型,并且能夠做到運行時改變值的能力,這就是多功能的典型特征。
因為C語言沒有構造式和解構式,所以客戶端只好傻傻的調用module_open,module_close并且,自動化的構造式和解構式容我有機會再介紹吧。
接下來看看神奇的模塊相關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,這就允許程序在運行時以動態方式載入共享庫或動態庫,而外部的shell只需要把.so準備好即可。
gcc poly_test.c -ldl
gcc -fPIC cola.c -shared -o libcola.so
LD_LIBRARY_PATH=./ ./a.out cola獲取可樂的價格:29
例子中的cola可以換成各種東西,例如sunflower或banana,只是記得要實踐libsunflower.so。
至於cola.c里面其實現就只有一個函數:get_price,而且很單純的return 29(反正量簡單比較好懂)
這種做法就將不同的實施方案封裝在共享庫中,而客戶端可以透過string去抽換功能,甚至更糟的是,連函數名都用string去抽換也行。
這些示例代碼都沒做error handle,要抄的人記得自己加(不然很容易SIGSEGV)
這種作法是把編譯時可以抓到的bug推遲到運行時去,如果你寫下來get_price形成get_prince,這個支程就掰了。
配套就是寫一個parser去建立symbol的綜合表并且去檢查所有的module_open是不是符合綜合表的內部內容,然后之后在Makefile內部調用這個parser做preprocess,如此即可完整其美,又有好的程序結構又能兼顧編譯時bug。
轉自:https://wirelessr.gitbooks.io/working-life/content/polymorphism_in_c.html
使用QJSEngine引擎編譯和運行JavaScript腳本時,你可以將JavaScript代碼保存在一個獨立的文件中,并使用QFile讀取該文件內容,然后使用QJSEngine的evaluate()方法執行該代碼。下面是一個示例,演示如何加載并執行一個獨立的JavaScript文件:
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QJSEngine>
#include <QJSValue>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 讀取JavaScript文件內容
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;
// 執行JavaScript腳本
QJSValue result=engine.evaluate(script);
// 檢查結果并輸出
if (result.isNumber()) {
int sum=result.toInt();
qDebug() << "Sum: " << sum;
} else {
qDebug() << "Error evaluating script!";
}
return a.exec();
}
在上面的示例中,我們首先使用QFile打開并讀取名為"script.js"的JavaScript文件的內容。然后,我們創建了一個QJSEngine對象,并使用evaluate()方法執行從文件中讀取的JavaScript代碼。最后,我們檢查結果的類型并輸出。
確保將實際的JavaScript文件命名為"script.js"并與可執行文件位于同一目錄下。你可以在JavaScript文件中編寫復雜的功能,包括定義函數、使用對象等。
這是一個簡單的示例,演示了如何使用QJSEngine引擎加載和執行一個獨立的JavaScript文件
*請認真填寫需求信息,我們會在24小時內與您取得聯系。