99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何給一個(gè)變量設(shè)置一個(gè)別名?

strongerHuang ? 來(lái)源:IOT物聯(lián)網(wǎng)小鎮(zhèn) ? 作者:IOT物聯(lián)網(wǎng)小鎮(zhèn) ? 2022-06-06 09:33 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

別名是啥玩意?

stackoverflow上看到一個(gè)有趣的話題:如何給一個(gè)變量設(shè)置一個(gè)別名?(How to assign to a variable an alias?

4eaada1e-e530-11ec-ba43-dac502259ad0.png

所謂的變量別名,就是通過(guò)通過(guò)不同的標(biāo)識(shí)符,來(lái)表示同一個(gè)變量。

我們知道,變量名稱是給程序員使用的。

編譯器的眼中,所有的變量都變成了地址

請(qǐng)注意:這里所討論的別名,僅僅是通過(guò)不同的標(biāo)識(shí)符來(lái)引用同一個(gè)變量。

與強(qiáng)符號(hào)、弱符號(hào)的概念沒(méi)有任何關(guān)系,那是另一個(gè)話題。

在上面這個(gè)帖子中,作者首先想到的是通過(guò)宏定義,對(duì)變量進(jìn)行重新命名。

這樣的做法,將會(huì)在編譯之前的預(yù)處理環(huán)節(jié),把宏標(biāo)識(shí)符替換為變量標(biāo)識(shí)符。

在網(wǎng)友回復(fù)的答案中,大部分都是通過(guò)指針來(lái)實(shí)現(xiàn):讓不同的標(biāo)識(shí)符指向同一個(gè)變量。

不管怎么說(shuō),這也算是一種別名了。

但是,這些答案有一個(gè)局限:這些代碼必須一起進(jìn)行編譯才可以,否則就可能出現(xiàn)無(wú)法找到符號(hào)的錯(cuò)誤信息。

現(xiàn)在非常流行插件編程,如果開(kāi)發(fā)者想在插件中通過(guò)一個(gè)變量別名來(lái)引用主程序中的變量,這該如何處理呢?

本文提供兩個(gè)方法來(lái)實(shí)現(xiàn)這個(gè)目的,并通過(guò)兩個(gè)簡(jiǎn)單的示例代碼來(lái)進(jìn)行演示。

文末有示例代碼的下載地址。

方法1:反向注冊(cè)

之前我接觸過(guò)一些CodeSys的代碼,里面的代碼質(zhì)量真的是非常的高,特別是軟件架構(gòu)設(shè)計(jì)部分。

傳說(shuō):CodySys 是工控界的 Android。

其中有個(gè)反向注冊(cè)的想法,正好可以用在變量別名上面。

示例代碼中一共有 2 個(gè)文件:main.cplugin.c。

main.c中定義了一個(gè)全局變量數(shù)組,編譯成可執(zhí)行程序main。

plugin.c中通過(guò)一個(gè)別名來(lái)使用main.c中的全局變量。

plugin.c被編譯成一個(gè)動(dòng)態(tài)鏈接庫(kù),被可執(zhí)行程序main動(dòng)態(tài)加載(dlopen)。

plugin.c中,提供一個(gè)函數(shù)func_init,當(dāng)動(dòng)態(tài)庫(kù)被main dlopen之后,這個(gè)函數(shù)就被調(diào)用,并且把真正的全局變量的地址通過(guò)參數(shù)傳入。

這樣的話,在插件中就可以通過(guò)一個(gè)別名來(lái)使用真正的變量了(比如:修改變量的值)。

本質(zhì)上,這仍然是通過(guò)指針來(lái)進(jìn)行引用。

只不過(guò)利用動(dòng)態(tài)注冊(cè)的思想,把指針與變量的綁定關(guān)系在時(shí)間和空間上進(jìn)行隔離。

plugin.c 源文件

#include 

int *alias_data = NULL;

void func_init(int *data)
{
printf("libplugin.so: func_init is called. 
");
alias_data = data;
}

void func_stage1(void)
{
printf("libplugin.so: func_stage1 is called. 
");
if (alias_data)
{
alias_data[0] = 100;
alias_data[1] = 200;
}
}

main.c 源文件

#include 
#include 
#include 

// defined in libplugin.so
typedef void (*pfunc_init)(int *);
typedef void (*pfunc_stage1)(void);

int data[100] = { 0 };


void main(void)
{
data[0] = 10;
data[1] = 20;

printf("data[0] = %d 
", data[0]);
printf("data[1] = %d 
", data[1]);

// open libplugin.so
void *handle = dlopen("./libplugin.so", RTLD_NOW);
if (!handle)
{
printf("dlopen failed. 
");
return;
}

// get and call init function in libplugin.so
pfunc_init func_init =  (pfunc_init) dlsym(handle, "func_init");
if (!func_init)
{
printf("get func_init failed. 
");
return;
}
func_init(data);

// get and call routine function in libplugin.so
pfunc_stage1 func_stage1 =  (pfunc_stage1) dlsym(handle, "func_stage1");
if (!func_stage1)
{
printf("get func_stage1 failed. 
");
return;
}
func_stage1();

printf("data[0] = %d 
", data[0]);
printf("data[1] = %d 
", data[1]);

return;
}

編譯指令如下:

gcc -m32 -fPIC --shared plugin.c -o libplugin.so
gcc -m32 -o main main.c -ldl

執(zhí)行結(jié)果:

data[0] = 10 
data[1] = 20 
libplugin.so: func_init is called. 
libplugin.so: func_stage1 is called. 
data[0] = 100 
data[1] = 200

可以看一下動(dòng)態(tài)鏈接庫(kù)的符號(hào)表:

readelf -s libplugin.so | grep data
4ee38580-e530-11ec-ba43-dac502259ad0.png

可以看到alias_data標(biāo)識(shí)符,并且是在本文件中定義的全局變量。

方法2:嵌入?yún)R編代碼

在動(dòng)態(tài)加載的插件中使用變量別名,除了上面演示的動(dòng)態(tài)注冊(cè)的方式,還可以通過(guò)嵌入?yún)R編代碼來(lái): 設(shè)置一個(gè)全局標(biāo)號(hào)來(lái)實(shí)現(xiàn)。

直接上示例代碼:

plugin.c源文件

#include 

asm(".Global alias_data");
asm("alias_data = data");

extern int alias_data[];

void func_stage1(void)
{
printf("libplugin.so: func_stage1 is called. 
");

*(alias_data + 0) = 100;
*(alias_data + 1) = 200;
}

main.c源文件

#include 
#include 
#include 

// defined in libplugin.so
typedef void (*pfunc_init)(int *);
typedef void (*pfunc_stage1)(void);

int data[100] = { 0 };


void main(void)
{
data[0] = 10;
data[1] = 20;

printf("data[0] = %d 
", data[0]);
printf("data[1] = %d 
", data[1]);

// open libplugin.so
void *handle = dlopen("./libplugin.so", RTLD_NOW);
if (!handle)
{
printf("dlopen failed. 
");
return;
}

// get and call routine function in libplugin.so
pfunc_stage1 func_stage1 =  (pfunc_stage1) dlsym(handle, "func_stage1");
if (!func_stage1)
{
printf("get func_stage1 failed. 
");
return;
}
func_stage1();

printf("data[0] = %d 
", data[0]);
printf("data[1] = %d 
", data[1]);

return;
}

編譯指令:

gcc -m32 -fPIC --shared plugin.c -o libplugin.so
gcc -m32 -rdynamic -o main main.c -ldl

執(zhí)行結(jié)果:

data[0] = 10 
data[1] = 20 
libplugin.so: func_stage1 is called. 
data[0] = 100 
data[1] = 200

也來(lái)看一下libplugin.so中的符號(hào)信息:

readelf -s libplugin.so | grep data
4f4798ea-e530-11ec-ba43-dac502259ad0.png

小結(jié)

這篇文檔通過(guò)兩個(gè)示例代碼,討論了如何在插件中(動(dòng)態(tài)鏈接庫(kù)),通過(guò)別名來(lái)訪問(wèn)真正的變量。

不知道您會(huì)不會(huì)有這樣的疑問(wèn):直接使用extern來(lái)聲明一下外部定義的變量不就可以了,何必這么麻煩?

道理是沒(méi)錯(cuò)!

但是,在一些比較特殊的領(lǐng)域或場(chǎng)景中(比如一些二次開(kāi)發(fā)中),這樣的需求是的確存在的,而且是強(qiáng)需求。

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4379

    瀏覽量

    64817
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4900

    瀏覽量

    70674
  • 變量
    +關(guān)注

    關(guān)注

    0

    文章

    614

    瀏覽量

    28942

原文標(biāo)題:如何給全局變量起一個(gè)別名?

文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Keysight是德示波器的5個(gè)觸發(fā)設(shè)置與波形分析方法

    Keysight是德示波器在電子測(cè)量領(lǐng)域應(yīng)用廣泛,精準(zhǔn)的觸發(fā)設(shè)置與高效的波形分析方法對(duì)獲取準(zhǔn)確信號(hào)信息至關(guān)重要。以下為您介紹5個(gè)常用的觸發(fā)設(shè)置及波形分析方法。 ? 邊沿觸發(fā)設(shè)置? 邊沿
    的頭像 發(fā)表于 06-27 16:00 ?242次閱讀
    Keysight是德示波器的5<b class='flag-5'>個(gè)</b>觸發(fā)<b class='flag-5'>設(shè)置</b>與波形分析方法

    關(guān)于STM32 CAN通信發(fā)送函數(shù)HAL_CAN_AddTxMessage()的最后個(gè)參數(shù)填0和定義個(gè)變量取地址的問(wèn)題求解

    問(wèn)題: 關(guān)于STM32 CAN通信 發(fā)送函數(shù) HAL_CAN_AddTxMessage()的最后個(gè)參數(shù)填0和定義個(gè)變量取地址的問(wèn)題,如果
    發(fā)表于 03-11 08:22

    個(gè)設(shè)置讓 KiCad 的視覺(jué)體驗(yàn)提升個(gè)檔次!

    “ ?不知道您有沒(méi)有感覺(jué)到無(wú)論是原理圖還是PCB,KiCad 沒(méi)有商業(yè)軟件看上去那么清晰?其實(shí)只需要手動(dòng)改下這個(gè)設(shè)置,瞬間讓您的視覺(jué)體驗(yàn)提升個(gè)檔次!? ” ? ? 使用 KiCad
    的頭像 發(fā)表于 02-17 11:17 ?935次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>個(gè)</b><b class='flag-5'>設(shè)置</b>讓 KiCad 的視覺(jué)體驗(yàn)提升<b class='flag-5'>一</b><b class='flag-5'>個(gè)</b>檔次!

    自己動(dòng)手做一個(gè)好玩的POV顯示設(shè)備

    “ 讀大學(xué)的時(shí)候就很喜歡這些開(kāi)腦洞的小玩意兒??吹?b class='flag-5'>一個(gè)印度小哥用ESP32 做了個(gè)高分辨率的 POV,而且開(kāi)源了全部的硬件和代碼,忍不住想分享大家?!?/div>
    的頭像 發(fā)表于 12-25 15:15 ?1080次閱讀
    自己動(dòng)手做<b class='flag-5'>一個(gè)</b>好玩的POV顯示設(shè)備

    如何構(gòu)建個(gè)演示移動(dòng)端應(yīng)用

    作為通訊工具,視頻會(huì)議幾乎隨處可見(jiàn),尤其適用于遠(yuǎn)程辦公和社交互動(dòng)。但其使用體驗(yàn)并非總是簡(jiǎn)單直接、即開(kāi)即用,可能需要進(jìn)行調(diào)整,確保音頻視頻設(shè)置良好。其中,照明便是個(gè)難以把握的因素。在會(huì)議中,光線充足
    的頭像 發(fā)表于 11-15 11:43 ?538次閱讀
    如何構(gòu)建<b class='flag-5'>一</b><b class='flag-5'>個(gè)</b>演示移動(dòng)端應(yīng)用

    分享個(gè)keil MDK編譯信息增強(qiáng)工具

    今天大家分享個(gè) keil MDK 編譯信息增強(qiáng)工具:keil-build-viewer. 1 keil-build-viewer介紹 這是
    的頭像 發(fā)表于 11-14 11:01 ?1841次閱讀

    如何在文本字段中使用上標(biāo)、下標(biāo)及變量

    在KiCad的任何文本字段中,都可以通過(guò)以下的方式實(shí)現(xiàn)上標(biāo)、下標(biāo)、上劃線以及顯示變量及字段值的描述: 文本變量“文本變量”可以在 原理圖設(shè)置->工程->文本
    的頭像 發(fā)表于 11-12 12:23 ?654次閱讀
    如何在文本字段中使用上標(biāo)、下標(biāo)及<b class='flag-5'>變量</b>

    Linux環(huán)境變量配置方法

    Linux上環(huán)境變量配置分為設(shè)置永久變量和臨時(shí)變量兩種。環(huán)境變量設(shè)置方法同時(shí)要考慮環(huán)境Shell
    的頭像 發(fā)表于 10-23 13:39 ?699次閱讀

    Xilinx設(shè)計(jì)工具怎么設(shè)置環(huán)境變量

    如果您不確定如何設(shè)置環(huán)境變量,嘗試"1" 或 "TRUE"。
    的頭像 發(fā)表于 10-22 13:32 ?608次閱讀

    雙開(kāi)關(guān)控制個(gè)燈怎么接線

    雙開(kāi)關(guān)控制個(gè)燈的接線方法主要有以下幾種,每種方法都有其特定的應(yīng)用場(chǎng)景和接線方式: 、串聯(lián)接線法 接線步驟 : 將電源線的火線(L)與個(gè)
    的頭像 發(fā)表于 10-09 15:57 ?1.3w次閱讀

    文帶你了解IP地址別名

    、什么是IP地址別名 IP地址別名是將多個(gè)IP地址與個(gè)網(wǎng)絡(luò)接口關(guān)聯(lián)起來(lái)的種方式。實(shí)現(xiàn)在網(wǎng)絡(luò)
    的頭像 發(fā)表于 09-05 14:11 ?541次閱讀

    ad如何設(shè)置個(gè)元器件的距離

    之間應(yīng)保持的最小距離,以確保電路板的電氣性能和制造過(guò)程的可靠性。以下是如何在AD中設(shè)置個(gè)元器件之間距離的步驟: 、進(jìn)入規(guī)則設(shè)置界面 打開(kāi)AD軟件 :首先,確保你已經(jīng)打開(kāi)了Altiu
    的頭像 發(fā)表于 09-02 15:31 ?1.7w次閱讀

    電感的電流能否分流一個(gè)電感

    電感的電流能否分流一個(gè)電感,這個(gè)問(wèn)題涉及到電感器的工作原理、特性以及在電路中的應(yīng)用。 電感器的基本概念 電感器是種被動(dòng)電子元件,其主要功能是存儲(chǔ)能量。電感器由
    的頭像 發(fā)表于 08-21 10:02 ?851次閱讀

    個(gè)socket對(duì)應(yīng)個(gè)連接嗎

    在探討“個(gè)socket對(duì)應(yīng)個(gè)連接”這命題時(shí),我們首先需要明確socket的基本概念和它在網(wǎng)絡(luò)通信中的作用。Socket,即套接字,是網(wǎng)
    的頭像 發(fā)表于 08-16 10:55 ?919次閱讀

    在PyTorch中搭建個(gè)最簡(jiǎn)單的模型

    在PyTorch中搭建個(gè)最簡(jiǎn)單的模型通常涉及幾個(gè)關(guān)鍵步驟:定義模型結(jié)構(gòu)、加載數(shù)據(jù)、設(shè)置損失函數(shù)和優(yōu)化器,以及進(jìn)行模型訓(xùn)練和評(píng)估。
    的頭像 發(fā)表于 07-16 18:09 ?2815次閱讀