国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++之深入解析如何通過(guò)extern “C”關(guān)鍵字支持C語(yǔ)言

這篇具有很好參考價(jià)值的文章主要介紹了C++之深入解析如何通過(guò)extern “C”關(guān)鍵字支持C語(yǔ)言。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、簡(jiǎn)介

  • C++ 語(yǔ)言的創(chuàng)建初衷是 “a better C”,但是這并不意味著 C++ 中類似 C 語(yǔ)言的全局變量和函數(shù)所采用的編譯和連接方式與 C 語(yǔ)言完全相同。作為一種欲與 C 兼容的語(yǔ)言, C++ 保留了一部分過(guò)程式語(yǔ)言的特點(diǎn)(被稱為“不徹底地面向?qū)ο蟆保?,因而它可以定義不屬于任何類的全局變量和函數(shù)。
  • 但是, C++ 畢竟是一種面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言,為了支持函數(shù)的重載, C++ 對(duì)全局函數(shù)的處理方式與 C 有明顯的不同,那么 C++ 中如何通過(guò) extern “C” 關(guān)鍵字支持 C 語(yǔ)言呢?

二、面試問(wèn)題

  • 某企業(yè)曾經(jīng)給出如下的一道面試題:為什么標(biāo)準(zhǔn)頭文件都有類似以下的結(jié)構(gòu)?
// incvxworks.h
#ifndef __INCvxWorksh
#define __INCvxWorksh

#ifdef __cplusplus
extern "C" {
#endif

/*...*/

#ifdef __cplusplus
}
#endif

#endif /* __INCvxWorksh */
  • 問(wèn)題分析:對(duì)于上面問(wèn)題,顯然頭文件中的編譯宏 #ifndef __INCvxWorksh、 #define __INCvxWorksh、 #endif 的作用是防止該頭文件被重復(fù)引用。那么,
#ifdef __cplusplus
extern "C" {
#endif#ifdef __cplusplus
}
#endif
  • 的作用又是什么呢?

三、關(guān)于 extern “C”

  • 前面的題目中的 __cplusplus 宏,是用來(lái)識(shí)別編譯器的,也就是說(shuō),將當(dāng)前代碼編譯的時(shí)候,是否將代碼作為 C++ 進(jìn)行編譯,如果是,則定義了 __cplusplus 宏。
  • 而題目中的 extern “C” 包含雙重含義,從字面上即可得到:首先,被它修飾的目標(biāo)是 extern 的;其次,被它修飾的目標(biāo)是 C 的。具體如下:被 extern “C” 限定的函數(shù)或變量是 extern 類型的。
  • extern 是 C/C++ 語(yǔ)言中表明函數(shù)和全局變量作用范圍(可見性)的關(guān)鍵字,該關(guān)鍵字告訴編譯器,其聲明的函數(shù)和變量可以在本模塊或其它模塊中使用。
  • 注意,語(yǔ)句 extern int a; 僅僅是對(duì)變量的聲明,其并不是在定義變量 a ,聲明變量并未為 a 分配內(nèi)存空間。定義語(yǔ)句形式為 int a; ,變量 a 在所有模塊中作為一種全局變量只能被定義一次,否則會(huì)出現(xiàn)連接錯(cuò)誤。
  • 在引用全局變量和函數(shù)之前,必須要有這個(gè)變量或者函數(shù)的聲明(或者定義)。通常,在模塊的頭文件中對(duì)本模塊提供給其它模塊引用的函數(shù)和全局變量以關(guān)鍵字 extern 聲明。例如,如果模塊 B 欲引用該模塊 A 中定義的全局變量和函數(shù)時(shí)只需包含模塊 A 的頭文件即可。這樣,模塊 B 中調(diào)用模塊 A 中的函數(shù)時(shí),在編譯階段,模塊 B 雖然找不到該函數(shù),但是并不會(huì)報(bào)錯(cuò);它會(huì)在連接階段中從模塊 A 編譯生成的目標(biāo)代碼中找到此函數(shù)。與 extern 對(duì)應(yīng)的關(guān)鍵字是 static ,被它修飾的全局變量和函數(shù)只能在本模塊中使用。因此,一個(gè)函數(shù)或變量只可能被本模塊使用時(shí),其不可能被 extern “C” 修飾。被 extern “C” 修飾的變量和函數(shù)是按照 C 語(yǔ)言方式編譯和連接的。
  • 首先看看 C++ 中,在未加 extern “C” 聲明時(shí),對(duì)類似 C 的函數(shù)是怎樣編譯的?
    • 作為一種面向?qū)ο蟮恼Z(yǔ)言, C++ 支持函數(shù)重載,而過(guò)程式語(yǔ)言 C 則不支持,因此函數(shù)被 C++ 編譯后在符號(hào)庫(kù)中的名字與 C 語(yǔ)言的有所不同;
    • 例如,假設(shè)某個(gè)函數(shù)的原型為:void foo( int x, int y ); 該函數(shù)被 C 編譯器編譯后在符號(hào)庫(kù)中的名字為 _foo ,而 C++ 編譯器則會(huì)產(chǎn)生像 _foo_int_int 之類的名字(不同的編譯器可能生成的名字不同,但是都采用了相同的機(jī)制,生成的新名字稱為 mangled name );
    • _foo_int_int 這樣的名字包含了函數(shù)名、函數(shù)參數(shù)數(shù)量及類型信息, C++ 就是靠這種機(jī)制來(lái)實(shí)現(xiàn)函數(shù)重載的。例如,在 C++ 中,函數(shù) void foo( int x, int y ) 與 void foo( int x, float y ) 編譯生成的符號(hào)是不相同的,后者為 _foo_int_float;
    • 同樣地, C++ 中的變量除支持局部變量外,還支持類成員變量和全局變量,用戶所編寫程序的類成員變量可能與全局變量同名,我們以 . 來(lái)區(qū)分;
    • 而本質(zhì)上,編譯器在進(jìn)行編譯時(shí),與函數(shù)的處理相似,也為類中的變量取了一個(gè)獨(dú)一無(wú)二的名字,這個(gè)名字與用戶程序中同名的全局變量名字不同。
  • 其次,看看在未加 extern “C” 聲明時(shí),是如何連接的?
    • 假設(shè)在 C++ 中,模塊 A 的頭文件如下:
// 模塊A頭文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
int foo( int x, int y );
#endif

在模塊 B 中引用該函數(shù):
// 模塊B實(shí)現(xiàn)文件 moduleB.cpp
#include "moduleA.h"
foo(2,3);
    • 實(shí)際上,在連接階段,連接器會(huì)從模塊 A 生成的目標(biāo)文件 moduleA.obj 中尋找 _foo_int_int 這樣的符號(hào)!,對(duì)于上面的例子,如果 B 模塊是 C 程序,而A模塊是 C++ 庫(kù)頭文件的話,會(huì)導(dǎo)致鏈接錯(cuò)誤;
    • 同理,如果 B 模塊是 C++ 程序,而 A 模塊是 C 庫(kù)的頭文件也會(huì)導(dǎo)致錯(cuò)誤。
  • 再者,看看加 extern “C” 聲明后的編譯和連接方式:
    • 加 extern “C” 聲明后,模塊 A 的頭文件變?yōu)椋?/li>
// 模塊A頭文件?moduleA.h 
#ifndef MODULE_A_H 
#define MODULE_A_H 
extern "C" int foo( int x, int y ); 
#endif
    • 在模塊 B 的實(shí)現(xiàn)文件中仍然調(diào)用 foo(2, 3) ,其結(jié)果將會(huì)是 C 語(yǔ)言的編譯連接方式:模塊 A 編譯生成 foo 的目標(biāo)代碼時(shí),沒(méi)有對(duì)其名字進(jìn)行特殊處理,采用了 C 語(yǔ)言的方式;連接器在為模塊 B 的目標(biāo)代碼尋找 foo(2, 3) 調(diào)用時(shí),尋找的是未經(jīng)修改的符號(hào)名 _foo;
    • 如果在模塊 A 中函數(shù)聲明了 foo 為 extern “C” 類型,而模塊 B 中包含的是 extern int foo( int x, int y ) ,則模塊 B 找不到模塊 A 中的函數(shù)(因?yàn)檫@樣的聲明沒(méi)有使用 extern “C” 指明采用C語(yǔ)言的編譯鏈接方式);反之亦然。
  • 綜上可知, extern “C” 這個(gè)聲明的真實(shí)目的,就是實(shí)現(xiàn) C++ 與 C 及其它語(yǔ)言的混合編程。C++ 引用 C 函數(shù)的具體例子 在 C++ 中引用 C 語(yǔ)言中的函數(shù)和變量,在包含 C 語(yǔ)言頭文件(假設(shè)為 cExample.h )時(shí),需進(jìn)行下列處理:
extern "C" {
    #include "cExample.h"
}
  • 因?yàn)椋?C 庫(kù)的編譯當(dāng)然是用 C 的方式生成的,其庫(kù)中的函數(shù)標(biāo)號(hào)一般也是類似前面所說(shuō)的 _foo 之類的形式,沒(méi)有任何參數(shù)信息,所以當(dāng)然在 C++ 中,要指定使用 extern “C” ,進(jìn)行 C 方式的聲明(如果不指定,那么 C++ 中的默認(rèn)聲明方式當(dāng)然是 C++ 方式的,也就是編譯器會(huì)產(chǎn)生 _foo_int_int 之類包含參數(shù)信息的、 C++ 形式的函數(shù)標(biāo)號(hào),這樣的函數(shù)標(biāo)號(hào)在已經(jīng)編譯好了的、可以直接引用的 C 庫(kù)中當(dāng)然沒(méi)有)。
  • 通過(guò)頭文件對(duì)函數(shù)進(jìn)行聲明,再包含頭文件,就能引用到頭文件中聲明的函數(shù)(因?yàn)楹瘮?shù)的實(shí)現(xiàn)在庫(kù)中呢,所以只聲明,然后鏈接就能用了)。而在 C 語(yǔ)言中,對(duì)其外部函數(shù)只能指定為 extern 類型,因?yàn)?C 語(yǔ)言中不支持 extern “C” 聲明,在 .c 文件中包含了 extern “C” 時(shí),當(dāng)然會(huì)出現(xiàn)編譯語(yǔ)法錯(cuò)誤。
  • 如下是一個(gè)具體代碼:
/* c語(yǔ)言頭文件:cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y);
#endif

/* c語(yǔ)言實(shí)現(xiàn)文件:cExample.c */
#include "cExample.h"
int add(int x, int y) {
    return x + y;
}

// c++實(shí)現(xiàn)文件,調(diào)用add:cppFile.cpp
extern "C" {
    #include "cExample.h"
}
int main(int argc, char* argv[]) {
    add(2,3);
    return 0;
}
  • 如果 C++ 調(diào)用一個(gè) C 語(yǔ)言編寫的 .DLL 時(shí),在包含 .DLL 的頭文件或聲明接口函數(shù)時(shí),應(yīng)加 extern “C” {?} 。這個(gè)時(shí)候,其實(shí) extern “C” 是在告訴 C++ ,鏈接 C 庫(kù)的時(shí)候,采用 C 的方式進(jìn)行鏈接(即尋找類似 _foo 的沒(méi)有參數(shù)信息的標(biāo)號(hào),而不是默認(rèn)的 _foo_int_int 這樣包含了參數(shù)信息的 C++ 標(biāo)號(hào))。
  • C 引用 C++ 函數(shù)的具體例子在 C 中引用 C++ 語(yǔ)言中的函數(shù)和變量時(shí), C++ 的頭文件需添加 extern “C” ,但是在 C 語(yǔ)言中不能直接引用聲明了 extern “C” 的該頭文件(因?yàn)镃語(yǔ)言不支持 extern “C” 關(guān)鍵字,所以會(huì)報(bào)編譯錯(cuò)誤),應(yīng)該僅在 C 文件中用 extern 聲明 C++ 中定義的 extern “C” 函數(shù),就是 C++ 中用 extern “C” 聲明的函數(shù)。
  • 在 C 中用 extern 來(lái)聲明一下,這樣 C 就能引用 C++ 的函數(shù),但是 C 中是不用用 extern “C” 的。如下所示:
// C++頭文件 cppExample.h
#ifndef CPP_EXAMPLE_H
#define CPP_EXAMPLE_H
extern "C" int add(int x, int y);
#endif

// C++實(shí)現(xiàn)文件 cppExample.cpp
#include "cppExample.h"
int add(int x, int y) {
    return x + y;
}

/* C實(shí)現(xiàn)文件 cFile.c
/* 這樣會(huì)編譯出錯(cuò):#include "cExample.h" */
extern int add( int x, int y );

int main(int argc, char* argv[]) {
    add(2, 3);   
    return 0;
}
  • 上面的例子, C 實(shí)現(xiàn)文件 cFile.c 不能直接用 #include “cExample.h”= 因?yàn)?=C 語(yǔ)言不支持 extern “C” 關(guān)鍵字。這個(gè)時(shí)候,而在 cppExample.h 中使用 extern “C” 修飾的目的是為了讓 C++ 編譯時(shí)候能夠生成 C 形式的符號(hào)(類似 _foo 不含參數(shù)的形式),然后將其添加到對(duì)應(yīng)的 C++ 實(shí)現(xiàn)庫(kù)中,以便被 C 程序鏈接到。
  • 對(duì) __BEGIN_DECLS 和 __END_DECLS 的理解在 C 語(yǔ)言代碼中頭文件中,經(jīng)??吹匠涑庵旅娴拇a片段:
1. __BEGIN_DECLS
2. .....
3. .....
4. __END_DECLS
  • 其實(shí),這些宏一般都是在標(biāo)準(zhǔn)庫(kù)頭文件中定義好了的,例如當(dāng)前機(jī)器的 sys/cdefs.h 中大致定義如下:
6. #if defined(__cplusplus)
7.        #define __BEGIN_DECLS extern "C" {
8.        #define __END_DECLS }
9.        #else
10.        #define __BEGIN_DECLS
11.        #define __END_DECLS
12. #endif
  • 這目的當(dāng)然是擴(kuò)充 C 語(yǔ)言在編譯的時(shí)候,按照 C++ 編譯器進(jìn)行統(tǒng)一處理,使得 C++ 代碼能夠調(diào)用 C 編譯生成的中間代碼。 由于 C 語(yǔ)言的頭文件可能被不同類型的編譯器讀取,因此寫 C 語(yǔ)言的頭文件必須慎重。因此,extern “C” 只是 C++ 的關(guān)鍵字,不是 C 的所以,如果在 C 程序中引入了 extern “C” 會(huì)導(dǎo)致編譯錯(cuò)誤。
  • 被 extern “C” 修飾的目標(biāo)一般是對(duì)一個(gè) C 或者 C++ 函數(shù)的聲明從源碼上看 extern “C” 一般對(duì)頭文件中函數(shù)聲明進(jìn)行修飾。無(wú)論 C 程序中的還是 cpp 中的頭文件,其函數(shù)聲明的形式都是一樣的(因?yàn)閮烧哒Z(yǔ)法基本一樣),對(duì)應(yīng)聲明的實(shí)現(xiàn)卻可能由于相應(yīng)的程序特性而不同了(C 庫(kù)和 C++ 庫(kù)里面當(dāng)然會(huì)不同)。
  • extern “C” 這個(gè)關(guān)鍵字聲明的真實(shí)目的,就是實(shí)現(xiàn) C++ 與 C 及其它語(yǔ)言的混合編程,一旦被 extern “C” 修飾之后,它便以 C 的方式工作,可以實(shí)現(xiàn)在 C 中引用 C++ 庫(kù)的函數(shù),也可以 C++ 中引用 C 庫(kù)的函數(shù)。

文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-434078.html

到了這里,關(guān)于C++之深入解析如何通過(guò)extern “C”關(guān)鍵字支持C語(yǔ)言的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • extern “C”關(guān)鍵字的作用

    extern \\\"C\\\" 是用于在C++中聲明使用C語(yǔ)言編寫的函數(shù)和變量的。C++和C在函數(shù)調(diào)用和變量命名等方面存在一些差異,為了在C++代碼中正確地使用C語(yǔ)言的函數(shù)和變量,需要使用extern \\\"C\\\"來(lái)進(jìn)行聲明。 函數(shù)重載(Function Overloading) : C++支持函數(shù)重載,即可以定義多個(gè)同名函數(shù),

    2024年02月10日
    瀏覽(15)
  • 深入理解C++中的靜態(tài)(Static)關(guān)鍵字及其應(yīng)用場(chǎng)景

    在C++中,靜態(tài)(Static)是一個(gè)常見且重要的概念,用于描述變量、函數(shù)和類成員。它具有獨(dú)特的特性和作用域,可以在不同的應(yīng)用場(chǎng)景中發(fā)揮重要作用。本文將詳細(xì)討論C++中的靜態(tài),包括靜態(tài)變量、靜態(tài)函數(shù)和靜態(tài)類成員,并對(duì)其與全局變量之間的區(qū)別進(jìn)行分析

    2024年02月09日
    瀏覽(31)
  • 【C++深入淺出】初識(shí)C++上篇(關(guān)鍵字,命名空間,輸入輸出,缺省參數(shù),函數(shù)重載)

    【C++深入淺出】初識(shí)C++上篇(關(guān)鍵字,命名空間,輸入輸出,缺省參數(shù),函數(shù)重載)

    ? ?? 目錄 一. 前言 二. 什么是C++ 三. C++初探 四. 命名空間 4.1 為什么要引入命名空間 4.2 命名空間的定義 4.3 命名空間使用 五. C++的輸入輸出 六. 缺省參數(shù) 6.1 缺省參數(shù)的概念 6.2 缺省參數(shù)的分類 七. 函數(shù)重載? 7.1 函數(shù)重載的概念 7.2 函數(shù)重載的條件 7.3 C++支持函數(shù)重載

    2024年02月13日
    瀏覽(1106)
  • 【C++深入淺出】初識(shí)C++下篇(auto關(guān)鍵字、范圍for、nullptr指針)

    【C++深入淺出】初識(shí)C++下篇(auto關(guān)鍵字、范圍for、nullptr指針)

    目錄 一. 前言 二. auto 2.1 auto的引入 2.2 auto簡(jiǎn)介 2.3 auto的使用細(xì)則 2.4?auto不能推導(dǎo)的場(chǎng)景 三. 基于范圍的for循環(huán)(C++11) 3.1 范圍for的語(yǔ)法 3.2 范圍for的原理 3.3 范圍for的使用條件 四. 指針空值nullptr(C++11) ? ? ? ? 上期我們介紹了c++新增的兩個(gè)重要語(yǔ)法:引用和內(nèi)聯(lián)函數(shù),今

    2024年02月11日
    瀏覽(114)
  • 如何基于運(yùn)維事件中心通過(guò) logstash 進(jìn)行日志關(guān)鍵字監(jiān)控

    日常運(yùn)維過(guò)程中,很多場(chǎng)景都需要對(duì)日志進(jìn)行監(jiān)測(cè),以便第一時(shí)間發(fā)現(xiàn)應(yīng)用/業(yè)務(wù)相關(guān)異常,這是一種比較常見的監(jiān)控需求,所以也有很多方法可以實(shí)現(xiàn)告警。對(duì)于簡(jiǎn)單的告警可以通過(guò)一些傳統(tǒng)的監(jiān)控工具實(shí)現(xiàn),但對(duì)于體量和業(yè)務(wù)是非常復(fù)雜的中大型企業(yè)來(lái)說(shuō),在

    2024年02月20日
    瀏覽(26)
  • C語(yǔ)言中volatile/register/const/static/extern/auto關(guān)鍵字的作用

    目錄 一、volatile 二、register詳解 三、const詳解 四、static詳解 五、extern詳解 語(yǔ)法 作用 六、auto詳解 突然想總結(jié)一下這些的作用,靈活使用這些對(duì)程序的可靠性和速率都有提高 volatile是防止編譯器優(yōu)化,如果是高頻繁的變量編譯器會(huì)自動(dòng)將變量放到寄存器中,但是有的變

    2024年02月07日
    瀏覽(25)
  • 【C++那些事兒】深入理解C++類與對(duì)象:從概念到實(shí)踐(下)| 再談構(gòu)造函數(shù)(初始化列表)| explicit關(guān)鍵字 | static成員 | 友元

    【C++那些事兒】深入理解C++類與對(duì)象:從概念到實(shí)踐(下)| 再談構(gòu)造函數(shù)(初始化列表)| explicit關(guān)鍵字 | static成員 | 友元

    ?? 江池?。簜€(gè)人主頁(yè) ?? 個(gè)人專欄:?C++那些事兒 ?Linux技術(shù)寶典 ?? 此去關(guān)山萬(wàn)里,定不負(fù)云起之望 1.1 構(gòu)造函數(shù)體賦值 在創(chuàng)建對(duì)象時(shí),編譯器通過(guò)調(diào)用構(gòu)造函數(shù),給對(duì)象中各個(gè)成員變量一個(gè)合適的初始值。 雖然上述構(gòu)造函數(shù)調(diào)用之后,對(duì)象中已經(jīng)有了一個(gè)初始值,但是

    2024年03月21日
    瀏覽(24)
  • 拼多多關(guān)鍵字搜索API-通過(guò)關(guān)鍵字獲取拼多多商品列表

    pinduoduo.item_search 公共參數(shù) 請(qǐng)求地址: pinduoduo/item_search 名稱 類型 必須 描述 key String 是 調(diào)用key(必須以GET方式拼接在URL中) secret String 是 調(diào)用密鑰 api_name String 是 API接口名稱(包括在請(qǐng)求地址中)[item_search,item_get,item_search_shop等] cache String 否 [yes,no]默認(rèn)yes,將調(diào)用緩存的數(shù)據(jù)

    2024年02月22日
    瀏覽(99)
  • C/C++ static關(guān)鍵字詳解(最全解析,static是什么,static如何使用,static的常考面試題)

    C/C++ static關(guān)鍵字詳解(最全解析,static是什么,static如何使用,static的??济嬖囶})

    目錄 一、前言 ?二、static是什么? 三、static修飾的對(duì)象是什么?? ?四、C 語(yǔ)言中的 static ???static的C用法 ???static的重點(diǎn)概念 ???static修飾局部變量 ???static在修飾局部變量和函數(shù)的作用 ???static修飾全局變量和函數(shù) ??static在修飾全局變量和函數(shù)的作用

    2024年02月05日
    瀏覽(20)
  • 面向?qū)ο缶幊蹋荷钊肜斫獬橄箢惡完P(guān)鍵字

    面向?qū)ο缶幊蹋荷钊肜斫獬橄箢惡完P(guān)鍵字

    在Java編程中,我們經(jīng)常會(huì)遇到一些特殊的和概念,其中包括static、final以及抽象類等。本文將深入探討這些和概念的作用和使用方法,并通過(guò)一個(gè)實(shí)例展示抽象類的應(yīng)用。 1. 1.1 static static修飾成員變量:表示該成員變量屬于類,不屬于對(duì)象,所有對(duì)象共享

    2024年02月15日
    瀏覽(28)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包