色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

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

真刀真槍模塊化(2.5)— 掩碼結(jié)構(gòu)體

電子設(shè)計(jì) ? 來(lái)源:電子設(shè)計(jì) ? 作者:電子設(shè)計(jì) ? 2020-12-14 21:00 ? 次閱讀
作者: GorgonMeducer 傻孩子
首發(fā):裸機(jī)思維


【說(shuō)在前面的話】


在本系列的前一篇文章《真刀真槍模塊化(2)——圖解Service模型》中,我們介紹了一種模塊化封裝的模型——Service模型。該模型的設(shè)計(jì)理念實(shí)際上服務(wù)于一個(gè)叫做“黑盒子哲學(xué)”的設(shè)計(jì)思維,其核心思想是:

  • 將模塊視作一個(gè)黑盒子:模塊的設(shè)計(jì)者不用向外透露黑盒子的實(shí)現(xiàn)細(xì)節(jié);同時(shí)模塊的使用者也無(wú)法看到黑盒子的內(nèi)部
  • 模塊的設(shè)計(jì)者和模塊的使用者完全通過(guò)“接口”來(lái)進(jìn)行約定和溝通。這里所有的接口約定都是通過(guò)接口頭文件來(lái)進(jìn)行描述和傳遞的。
  • 接口(及接口頭文件)遵循“最小信息公開(kāi)原則”,即,任何跟使用模塊所提供的服務(wù)無(wú)關(guān)的、或者非必要(可有可無(wú))信息都應(yīng)該從接口頭文件中刪除。

實(shí)踐中,要想實(shí)現(xiàn)黑盒子,我們實(shí)際上要完成兩大任務(wù):

  1. 如何隱藏模塊的實(shí)現(xiàn),或者說(shuō)隱藏源代碼;
  2. 接口頭文件中數(shù)據(jù)結(jié)構(gòu)的保護(hù),或者說(shuō)如何阻止用戶繞開(kāi)模塊所提供的API而直接訪問(wèn)關(guān)鍵結(jié)構(gòu)體的內(nèi)部(私有)成員

對(duì)于第一條來(lái)說(shuō),我們只需要把模塊編譯成library,連同接口頭文件一起提供給客戶使用就可以做到;而對(duì)于第二條要想實(shí)現(xiàn)起來(lái)卻并非那么簡(jiǎn)單——雖然我們常常說(shuō)C語(yǔ)言可以通過(guò)結(jié)構(gòu)體來(lái)模擬類的概念,但它卻無(wú)法像C++的類那樣提供對(duì)私有(private)和受保護(hù)(protected)成員的隱藏。換句話說(shuō),在實(shí)踐“最小信息公開(kāi)原則”的時(shí)候,如果用戶調(diào)用服務(wù)的時(shí)候,確實(shí)需要用到結(jié)構(gòu)體(這個(gè)結(jié)構(gòu)體是最小信息),如何防止結(jié)構(gòu)體的定義信息被“非法使用”,就成了一個(gè)切實(shí)的難題。
為了讓后續(xù)的討論更為清晰,我們不妨具體的定義一下我們的任務(wù):

  • 只允許用戶使用結(jié)構(gòu)體的大小對(duì)齊信息——這樣用戶可以自由的定義變量,或是通過(guò)malloc這樣的函數(shù)進(jìn)行動(dòng)態(tài)分配;
  • 以某種“通過(guò)實(shí)際手段強(qiáng)制了的君子協(xié)定”的形式——僅在語(yǔ)法層面——阻止用戶直接訪問(wèn)結(jié)構(gòu)體的成員。

要想同時(shí)做到以上兩點(diǎn),離不開(kāi)今天索要介紹的主角:掩碼結(jié)構(gòu)體(Masked Structure)。
【什么是掩碼結(jié)構(gòu)體】


要想理解掩碼結(jié)構(gòu)體,拋開(kāi)復(fù)雜和抽象的文字描述,我們不妨來(lái)看一個(gè)具體的例子:假設(shè)我們做了一個(gè)字節(jié)隊(duì)列的模塊,其中最核心的結(jié)構(gòu)體 byte/_queue/_t 的定義如下:

typedef struct byte_queue_t byte_queue_t;

針對(duì)這一結(jié)構(gòu)體(或者叫類)我們提供一系列API(或者叫類的方法),比如:

typedef struct byte_queue_cfg_t {

為了保證模塊的正常工作,防止運(yùn)行期間,用戶為了自身的便利,直接”外科手術(shù)式的“訪問(wèn) byte/_queue/_t 的成員導(dǎo)致不必要的問(wèn)題(比如用戶說(shuō):我知道你遵循的是最小信息公開(kāi)原則,也就是說(shuō),只要你放了結(jié)構(gòu)體在接口頭文件里,我當(dāng)然理解為我可以任意使用咯?),我們想將整個(gè) byte/_queue/_t 都保護(hù)起來(lái)——這就好比,我們?cè)噲D引入一個(gè)“蒙版”,遮住結(jié)構(gòu)體的成員信息然后在客戶的耳邊念起魔咒:
你什么都看不到,你看到了也沒(méi)法用……
你什么都看不到,你看到了也沒(méi)法用……
你什么都看不到,你看到了也沒(méi)法用……

...

要想實(shí)現(xiàn)這樣的“蒙版效果”其實(shí)并不困難,只需要知道要屏蔽的部分實(shí)際占用memory的大小,再根據(jù)這一大小來(lái)定義數(shù)組即可,因此,我們可以修改對(duì)應(yīng)的定義為:

typedef struct byte_queue_t byte_queue_t;

這里,我們實(shí)際上是給原來(lái)的類型重命名為/_/_byte/_queue/_t,并建立了一個(gè)內(nèi)部只使用數(shù)組來(lái)“濫竽充數(shù)”的替身——也就是我們所說(shuō)的掩碼結(jié)構(gòu)體。

如果你看過(guò)我之前的文章《漫談C變量——對(duì)齊(3)》,你會(huì)注意到,上述替身實(shí)際上丟失了結(jié)構(gòu)體 /_/_byte/_queue/_t 的對(duì)齊信息——容易注意到 struct /_/_byte/_queue/_t 的結(jié)構(gòu)體整體是對(duì)齊到 4 字節(jié)的,而掩碼結(jié)構(gòu)體中數(shù)組chMask本身是對(duì)齊到字節(jié)的——這會(huì)導(dǎo)致當(dāng)用戶使用掩碼結(jié)構(gòu)體來(lái)定義變量時(shí),由編譯器分配的空間可能無(wú)法滿足原結(jié)構(gòu)體對(duì)對(duì)齊的要求,造成非對(duì)齊訪問(wèn)——輕則性能下降,重則hardfault。

要解決這一問(wèn)題也并不復(fù)雜,只需要借助GCC擴(kuò)展的運(yùn)算符 /_/_alignof/_/_() 提取目標(biāo)類型的對(duì)齊信息,再使用/_/_attribute/_/_((aligned())) 來(lái)設(shè)置掩碼數(shù)組的對(duì)齊要求就可以了:

typedef struct byte_queue_t byte_queue_t;

至此,掩碼結(jié)構(gòu)體 byte/_queue/_t 擁有了和原本的結(jié)構(gòu)體 struct /_/_byte/_queue/_t 一樣的尺寸和對(duì)齊;同時(shí)還在“語(yǔ)法”層面阻止了用戶直接訪問(wèn)結(jié)構(gòu)體成員的可能(當(dāng)然,這也只能防君子不防小人),我們?cè)驹O(shè)立的兩個(gè)目標(biāo)都已成功達(dá)成。然而,聰明的你會(huì)在腦海里浮現(xiàn)出一個(gè)疑問(wèn)——要想掩碼結(jié)構(gòu)體能正常工作,上述信息都必須放置到接口頭文件中,難道用戶是傻子,看不到結(jié)構(gòu)體 /_/_byte/_queue/_t 么?

借助宏的力量,我們可以成功的隱藏住 struct /_/_byte/_queue/_t 的存在。


下面的宏只是為了演示一種簡(jiǎn)單的實(shí)現(xiàn)方法,暫時(shí)的打消你的疑慮,而實(shí)際在后面我們將要介紹的PLOOC模板中所使用的技法則更為復(fù)雜。由于本文只是著重于實(shí)際工程實(shí)踐中如何簡(jiǎn)單的應(yīng)用掩碼結(jié)構(gòu)體,而不在于介紹復(fù)雜的宏技巧,因此我們將不在討論 PLOOC的實(shí)現(xiàn)細(xì)節(jié)。


#definedeclare_class(__name)     /

借助上述宏,我們可以將接口頭文件 byte/_queue.h 中代碼簡(jiǎn)化為:

...

而模塊源代碼中,則可以使用 class/_internal() 來(lái)獲取原本的結(jié)構(gòu)體類型:

...

【如何使用PLOOC來(lái)簡(jiǎn)化開(kāi)發(fā)】


PLOOCProtected Low-overheadObject-Oriented programming with ANSI-C的英文縮寫(xiě),意為:為(類)提供保護(hù)的、低開(kāi)銷(xiāo)的、面向?qū)ο驝語(yǔ)言開(kāi)發(fā)。它是我在 Github 上的一個(gè)開(kāi)源項(xiàng)目(https://github.com/GorgonMedu...)。PLOOC 是目前已知唯一使用掩碼結(jié)構(gòu)體對(duì)私有(private)和受保護(hù)(protected)的成員提供隱藏的OOPC模板;除此以外,通過(guò)幾近于0的額外資源消耗來(lái)實(shí)現(xiàn)面向?qū)ο蠓庋b特性,也是PLOOC的一大賣(mài)點(diǎn)。

雖然PLOOC自帶的 MDK 例子工程演示了常見(jiàn)的面向?qū)ο筇匦裕幱跁r(shí)間問(wèn)題,仍然沒(méi)有來(lái)得及提供一份簡(jiǎn)單直接的手把手使用教程。這里我們?nèi)匀灰?byte/_queue/_t 為例,為大家介紹一下如何在自己的工程中部署 PLOOC,并應(yīng)用到 service模型中。

準(zhǔn)備階段

  • 從Github上下載最新的 release 版本。

  • 解壓縮后重命名目錄為 PLOOC,并復(fù)制到你的目標(biāo)工程中

  • 在你的工程中添加對(duì)PLOOC目錄的引用

  • 在工程配置中打開(kāi)對(duì) C99 的支持,如果可能,直接開(kāi)啟 C11和GNU擴(kuò)展的支持:

  • 如果你使用的是 gcc, clang 或是 arm compiler 6,你還需要打開(kāi)對(duì)微軟擴(kuò)展的支持(-fms-extensions)并屏蔽一些惱人且無(wú)害的 warning:
-fms-extensions -Wno-microsoft-anon-tag -Wno-empty-body


NOTE:如果你使用的是 arm compiler 6,在開(kāi)啟微軟擴(kuò)展以后,還需要額外定義一個(gè)宏 /_MSC/_VER 來(lái)避免底層庫(kù)中的一些不必要的編譯錯(cuò)誤。
至此,我們就完成了 PLOOC 在你工程中的部署。

如何在模塊中部署

仍以 byte/_queue 模塊為例,假設(shè)你已經(jīng)根據(jù) service 模型構(gòu)建好了目錄結(jié)構(gòu):

  • 打開(kāi)接口頭文件 byte/_queue.h 并在靠近結(jié)構(gòu)體定義的地方其中添加以下內(nèi)容:
/*! /NOTE: Make sure #include "plooc_class.h" is close to the class definition 

這里,我們定義了兩個(gè)很重要的宏 /_/_BYTE/_QUEUE/_CLASS/_IMPLEMENT/_/_BYTE/_QUEUE/_CLASS/_INHERIT/_/_。容易看出,他們分別是根據(jù)

__<模塊名稱>_CLASS_IMPLEMENT

__<模塊名稱>_CLASS_INHERIT__

的形式改寫(xiě)而成的。前者的作用是給 C 源代碼標(biāo)記“我是這個(gè)類的實(shí)現(xiàn),我是類的主人”的身份用的;后者的作用是給 C代碼標(biāo)記“我是派生類的實(shí)現(xiàn),我派生自基類”。具體使用方法,后面會(huì)具體介紹。
需要特別強(qiáng)調(diào)的是,一定不要忘記在接口頭文件的尾部將這兩個(gè)宏都undef掉

...
  • 在 byte/_queue.h 里定義目標(biāo)類:
//! /name class byte_queue_t

值得注意的是,這里我們用 private/_member()protected/_member()的形式規(guī)定了成員變量的屬性:其中private的成員是只有類的主人自己可見(jiàn);而 protected的成員是類的主人以及派生類都可見(jiàn)。如果你想指定某些成員是公共可見(jiàn)的,則可以使用 public/_member()

  • 打開(kāi) byte/_queue.c,在文件的最開(kāi)始通過(guò)定義宏 /_/_BYTE/_QUEUE/_CLASS/_IMPLEMENT 來(lái)標(biāo)記自己“類主人”的身份,當(dāng)然,別忘記包含自己的接口頭文件:
#define __BYTE_QUEUE_CLASS_IMPLEMENT
  • 在 byte/_queue.c 中,如果某個(gè)函數(shù)(類的方法)試圖訪問(wèn)類的成員,則應(yīng)該首先借助 class/_internal() 來(lái)“脫下馬甲”。方法跟前文一樣,這里就不再贅述。

完整的例子在 PLOOC 的example目錄下:諸如派生類應(yīng)該如何處理函數(shù)重載應(yīng)該如何實(shí)現(xiàn)等等問(wèn)題,大家可以打開(kāi)MDK的例子工程后“細(xì)品”。

【后記】


掩碼結(jié)構(gòu)體是一種全新的方法,可以在語(yǔ)法層面上限制模塊的使用者對(duì)關(guān)鍵的結(jié)構(gòu)體(類)成員的訪問(wèn)。相比大家熟悉的“不完全類型”,掩碼結(jié)構(gòu)體攜帶了足夠的信息(大小信息和對(duì)齊信息),從而允許模塊的使用者自由的定義變量或是動(dòng)態(tài)分配,這與“不完全類型”必須依賴動(dòng)態(tài)分配的缺點(diǎn)形成了鮮明的對(duì)比。
曾幾何時(shí),掩碼結(jié)構(gòu)體還有“模塊的.c不能包含模塊的接口頭文件” 這樣的限定,在最新的PLOOC中,這一問(wèn)題已經(jīng)得到了徹底的解決——再也不用擔(dān)心 ".c" 和 ".h" 中的類型描述不一致導(dǎo)致的運(yùn)行時(shí)錯(cuò)誤。
最后,需要強(qiáng)調(diào)一下,對(duì) service 模型來(lái)說(shuō),掩碼結(jié)構(gòu)體,或者說(shuō)PLOOC的使用只是“錦上添花”——并非必須。讀者完全可以根據(jù)自己的喜好來(lái)決定模塊的實(shí)現(xiàn)方式。如果你喜歡或者對(duì)PLOOC使用有什么建議,歡迎在 github上提交你的issue。


審核編輯 黃昊宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(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)投訴
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    模塊化結(jié)構(gòu)與同容量分立器件結(jié)構(gòu)的不同

    模塊化結(jié)構(gòu)提高了產(chǎn)品的密集性、安全性和可靠性,同時(shí)也可降低裝置的生產(chǎn)成本,縮短新產(chǎn)品進(jìn)入市場(chǎng)的周期,提高企業(yè)的市場(chǎng)競(jìng)爭(zhēng)力。由于電路的聯(lián)線已在模塊內(nèi)部完成,因此,縮短了元器件之間的連線,可實(shí)現(xiàn)優(yōu)化布線
    發(fā)表于 09-09 09:15

    模塊化程序設(shè)計(jì)

    模塊化程序設(shè)計(jì)思想,單片機(jī)c語(yǔ)言的模塊化設(shè)計(jì),方便移植,將程序封裝備用。
    發(fā)表于 03-22 15:29 ?9次下載

    AMD二代霄龍迎來(lái)歷史上的最佳機(jī)遇

    AMD Ryzen銳龍這兩年讓微處理器乃至是整個(gè)PC領(lǐng)域煥發(fā)了新的勃勃生機(jī),喜聞樂(lè)見(jiàn)的真刀真槍激烈競(jìng)爭(zhēng)重現(xiàn)江湖,是整個(gè)行業(yè)以及所有消費(fèi)者的福音。
    發(fā)表于 07-02 15:17 ?592次閱讀

    愛(ài)立信:5G提前開(kāi)花結(jié)果,中國(guó)市場(chǎng)期待真正收獲

    在5G真刀真槍的開(kāi)啟商用元年之后,百年老店也持續(xù)露出復(fù)蘇態(tài)勢(shì)。
    的頭像 發(fā)表于 07-22 11:26 ?2016次閱讀

    西門(mén)子s7-300模塊化結(jié)構(gòu)及組成部分

    基本的模塊化硬件結(jié)構(gòu)結(jié)構(gòu)包括機(jī)架、電源、處理器CPU、輸入輸出I/O模塊、編程或通訊用接口,圖1表示了一個(gè)模塊化控制器是如何由
    的頭像 發(fā)表于 02-22 06:56 ?1.9w次閱讀
    西門(mén)子s7-300<b class='flag-5'>模塊化</b><b class='flag-5'>結(jié)構(gòu)</b>及組成部分

    模塊化UPS電源的分布結(jié)構(gòu)

    分布式是早期模塊化UPS經(jīng)常使用的一種架構(gòu)。此類模塊化UPS系統(tǒng)層面上等價(jià)于數(shù)臺(tái)獨(dú)立的UPS直接并聯(lián),其功率模塊利用小型UPS改造而成,可自主獨(dú)立工作。
    發(fā)表于 05-29 10:25 ?1535次閱讀

    真刀真槍模塊化(2)—圖解Service模型

    作者: GorgonMeducer 傻孩子首發(fā):裸機(jī)思維 【說(shuō)在前面的話】在前面一篇文章《真刀真槍模塊化(1)——一本糊涂賬》中,我們討論了:在工...
    的頭像 發(fā)表于 12-14 22:38 ?514次閱讀

    FPGA模塊化設(shè)計(jì)與AlteraHardCopy結(jié)構(gòu)化ASIC

    本文檔的主要內(nèi)容詳細(xì)介紹的是FPGA模塊化設(shè)計(jì)與AlteraHardCopy結(jié)構(gòu)化ASIC。
    發(fā)表于 01-20 17:03 ?6次下載
    FPGA<b class='flag-5'>模塊化</b>設(shè)計(jì)與AlteraHardCopy<b class='flag-5'>結(jié)構(gòu)化</b>ASIC

    華為模塊化數(shù)據(jù)中心解決方案顯著提升模塊化建筑結(jié)構(gòu)的抗震性能

    近日,華為聯(lián)合同濟(jì)大學(xué)申報(bào)的預(yù)制模塊化數(shù)據(jù)中心解決方案磐石架構(gòu)技術(shù)——箱式模塊化數(shù)據(jù)中心建筑結(jié)構(gòu)設(shè)計(jì)技術(shù)與設(shè)計(jì)軟件開(kāi)發(fā)技術(shù),榮獲中國(guó)建筑學(xué)會(huì)科技進(jìn)步獎(jiǎng)。這是繼2020年,該技術(shù)獲上海市建筑學(xué)會(huì)科技進(jìn)步獎(jiǎng)后,再次實(shí)現(xiàn)“跨界出圈”,
    的頭像 發(fā)表于 11-20 14:15 ?3147次閱讀

    真刀真槍模塊化(3.5)——騷操作?不!這才是正統(tǒng)

    首發(fā):裸機(jī)思維作者: GorgonMeducer 傻孩子【你可曾懷疑過(guò)?】C語(yǔ)言寫(xiě)多了,或多或少會(huì)聽(tīng)說(shuō)一些“上古傳下來(lái)”的教條,比如:include 語(yǔ)...
    發(fā)表于 01-25 18:28 ?0次下載
    <b class='flag-5'>真刀真槍</b><b class='flag-5'>模塊化</b>(3.5)——騷操作?不!這才是正統(tǒng)

    真刀真槍模塊化(3)—— 層次框架初探

    作者: GorgonMeducer 傻孩子首發(fā):裸機(jī)思維(圖片來(lái)自網(wǎng)絡(luò),侵刪) 【說(shuō)在前面的話】在本系列的前面幾篇文章中,我們依次討論了如下的幾...
    發(fā)表于 01-25 19:44 ?0次下載
    <b class='flag-5'>真刀真槍</b><b class='flag-5'>模塊化</b>(3)—— 層次框架初探

    真刀真槍模塊化(1)——一本糊涂賬

    對(duì)很多人來(lái),嵌入式軟件開(kāi)發(fā)過(guò)程中?模塊化(Modularization)是一個(gè)海市蜃樓、是一個(gè)書(shū)面詞匯、是一個(gè)過(guò)氣的時(shí)尚——模塊化似乎從未真正的...
    發(fā)表于 01-26 19:33 ?0次下載
    <b class='flag-5'>真刀真槍</b><b class='flag-5'>模塊化</b>(1)——一本糊涂賬

    什么是模塊化自動(dòng)

    什么是模塊化自動(dòng)
    的頭像 發(fā)表于 03-10 16:29 ?2878次閱讀
    什么是<b class='flag-5'>模塊化</b>自動(dòng)<b class='flag-5'>化</b>?

    歐姆龍模塊化編程的使用技巧

    【導(dǎo)讀】在平常使用歐姆龍SysmacStudio 編程時(shí),有新建大量的結(jié)構(gòu)和全局變量,若不分類進(jìn)行模塊化,會(huì)造成查找不方便,下面分享的就是對(duì)全局變量和數(shù)據(jù)類型進(jìn)行模塊分類,方便查找,
    的頭像 發(fā)表于 03-17 17:45 ?2044次閱讀

    PLC模塊化結(jié)構(gòu)化編程實(shí)例

    模塊化編程中OB1起著主程序的作用,F(xiàn)C或FB控制著不同的過(guò)程任務(wù),相當(dāng)于主循環(huán)程序的子程序。模塊化編程中被調(diào)用塊不向調(diào)用塊返回?cái)?shù)據(jù)。
    的頭像 發(fā)表于 07-10 14:42 ?1063次閱讀
    PLC<b class='flag-5'>模塊化</b>和<b class='flag-5'>結(jié)構(gòu)化</b>編程實(shí)例
    主站蜘蛛池模板: 久久国产精品免费A片蜜芽| 妻子的秘密HD观看| 国产麻豆精品久久一二三| 国产精品久久久久久久人热| 国产精品成人A蜜柚在线观看| 国产成人综合在线| 国外经典三级| 啦啦啦 中文 日本 韩国 免费| 美女大本营| 青青热久久综合网伊人| 天海翼精品久久中文字幕| 亚洲精品久久久久AV无码| 中文国产成人精品久久免费| 99精品国产AV一区二区麻豆| 欧美一区二区视频97色伦| 日本aa大片| 小萝ar视频网站| 在线观看中文| 被两根巨大同时进去高H| 国产精品爽黄69天堂A片| 久久99精品视频| 欧美亚洲色帝国| 校草让我脱了内裤给全班看| 伊人久在线| 扒开校花粉嫩小泬喷潮漫画| 国产免费啪嗒啪嗒视频看看 | 亚洲日本欧美产综合在线| 4399亚洲AV无码V无码网站| 成年私人影院网站在线看| 国产亚洲精品久久久久小| 麻豆久久国产亚洲精品超碰热| 日韩欧美三区| 一个人的免费完整在线观看HD| u15女少天堂写真| 亚洲午夜精品AV无码少妇| 国产自产第一区c国产| 野花4在线观看| 夜色伊甸园| 公主纯肉高H文| 妇少水多18P蜜泬17P亚洲乱| 日韩欧美精品有码在线播放免费|