中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

手機(jī)怎么做網(wǎng)站賣東西營(yíng)銷技巧美劇

手機(jī)怎么做網(wǎng)站賣東西,營(yíng)銷技巧美劇,隨州網(wǎng)站制作,020網(wǎng)站開發(fā)多少錢C# 使用 "3f/DllExport" 工具導(dǎo)出C風(fēng)格的本機(jī)函數(shù) [文 / 張賜榮] 首先,讓我們來(lái)了解一下什么是爭(zhēng)渡讀屏軟件,以及什么是爭(zhēng)渡文本預(yù)處理API。爭(zhēng)渡讀屏軟件是一款屏幕朗讀軟件,用于協(xié)助視力障礙人士操作電腦。 爭(zhēng)渡文本預(yù)處理API是一…

????????????????C# 使用 "3f/DllExport" 工具導(dǎo)出C風(fēng)格的本機(jī)函數(shù)


[文 / 張賜榮]

首先,讓我們來(lái)了解一下什么是爭(zhēng)渡讀屏軟件,以及什么是爭(zhēng)渡文本預(yù)處理API。爭(zhēng)渡讀屏軟件是一款屏幕朗讀軟件,用于協(xié)助視力障礙人士操作電腦。
爭(zhēng)渡文本預(yù)處理API是一種讓插件可以修改讀屏朗讀的文本的接口,它是一個(gè)32位的動(dòng)態(tài)鏈接庫(kù)(DLL),文件名為ZDTextPreprocess.dll,放在"爭(zhēng)渡讀屏安裝目錄\addins"下。讀屏?xí)?yōu)先加載這個(gè)DLL文件,然后調(diào)用其中的兩個(gè)函數(shù):Init和TextPreprocess。
"Init"函數(shù)是用來(lái)初始化插件的,它沒(méi)有參數(shù),只返回一個(gè)整數(shù)值,表示當(dāng)前插件的版本號(hào)。這個(gè)版本號(hào)應(yīng)該和文檔中的版本號(hào)一致,目前是1。
"TextPreprocess"函數(shù)是用來(lái)對(duì)文本進(jìn)行預(yù)處理的,它有兩個(gè)參數(shù):oldString和newString。oldString是一個(gè)寬字符指針,指向讀屏即將朗讀的原始文本。newString也是一個(gè)寬字符指針,指向插件修改后的新文本,它的緩沖區(qū)大小為40960字節(jié),如果超出了這個(gè)大小,需要截?cái)喽嘤嗟牟糠?。這個(gè)函數(shù)返回一個(gè)整數(shù)值,表示新文本的長(zhǎng)度。如果發(fā)生了錯(cuò)誤,或者沒(méi)有替換文本,就返回0。
插件開發(fā)者可以根據(jù)自己的需求,編寫TextPreprocess函數(shù)的邏輯,實(shí)現(xiàn)對(duì)讀屏朗讀文本的定制化修改。例如,可以替換一些特殊符號(hào),或者添加一些注釋等。
接下來(lái),讓我們來(lái)看看如何用C#來(lái)編寫爭(zhēng)渡文本預(yù)處理插件。我們需要使用一個(gè)叫"3f/DllExport"的工具,它可以讓.NET程序集導(dǎo)出本機(jī)風(fēng)格的函數(shù)。這樣我們就可以用C#來(lái)編寫類似于C語(yǔ)言生成的DLL一樣的插件了。
"3f/DllExport"是一個(gè)開源項(xiàng)目,在GitHub上可以找到它的源代碼和文檔。它是在"Unmanaged Exports"基礎(chǔ)上發(fā)展而來(lái)的。"Unmanaged Exports"是一個(gè)早期的嘗試,它也可以讓.NET程序集導(dǎo)出函數(shù),但是它有很多問(wèn)題,而且已經(jīng)很久沒(méi)有更新了。
"3f/DllExport"的工作原理是修改了.NET生成的DLL,在其中插入了本機(jī)DLL的頭以及導(dǎo)出函數(shù)表、重定位函數(shù)表信息等。這樣,它就像一個(gè)普通的本機(jī)DLL一樣,可以被任何支持調(diào)用本機(jī)DLL的語(yǔ)言或平臺(tái)使用。當(dāng)然,它本質(zhì)上并不是真正的本機(jī)DLL,它的執(zhí)行代碼依然是IL(中間語(yǔ)言)而不是本機(jī)二進(jìn)制代碼,所以本身還是要依賴.NET運(yùn)行時(shí)。只是因?yàn)楝F(xiàn)在有了導(dǎo)出函數(shù)表,并且加入了類似于普通DLL的頭信息,看起來(lái)就與普通C語(yǔ)言導(dǎo)出的DLL相似。
這與最新的.NET 7 Native AOT不一樣,那個(gè)是真正地編譯為了非托管本機(jī)代碼,可以脫離.NET運(yùn)行時(shí)。但是.NET 7 Native AOT不支持X86(32位),而易語(yǔ)言只支持X86的DLL。所以對(duì)于我們來(lái)說(shuō),并沒(méi)有什么用處。
我不知道為什么微軟官方?jīng)]有去做這樣的支持,反而還需要第三方工具來(lái)修改。
不過(guò),既然有了這樣一個(gè)好用的工具,就不用再抱怨了。我們可以利用它來(lái)實(shí)現(xiàn)我們想要的功能,而不用再去學(xué)習(xí)和使用C++或其他語(yǔ)言??梢杂肅#的強(qiáng)大功能和豐富的庫(kù),來(lái)編寫更多的文本預(yù)處理效果。
那么"3f/DllExport"怎么使用呢?下面我就以編寫爭(zhēng)渡文本預(yù)處理插件為例,給大家做一個(gè)簡(jiǎn)單的教程。
首先,我們需要下載"3f/DllExport"這個(gè)工具。我們可以前往它的GitHub頁(yè)面,找到它的最新版本,目前是"v1.7.4 (Latest on Jan 3, 2021)",文件名應(yīng)該是"offline.DllExport.1.7.4.29858.c1cc52f.zip"。我們下載并解壓這個(gè)文件,可以看到里面有很多文件和文件夾。
接著,我們需要打開Visual Studio 2019,新建一個(gè).NET Framework類庫(kù)項(xiàng)目,名字叫"TextPreprocessAddon"。然后關(guān)閉Visual Studio,將剛才解壓的文件全部復(fù)制到我們的解決方案文件夾下(也就是與*.sln同目錄的文件夾)。然后運(yùn)行目錄中的"DllExport.bat"進(jìn)行配置。打開后有很多配置和選項(xiàng),我們暫時(shí)不用管,勾選"Installed"復(fù)選框,然后點(diǎn)擊"Apply"應(yīng)用設(shè)置。它會(huì)修改我們的項(xiàng)目配置文件,讓它支持導(dǎo)出函數(shù)。
配置DllExport就基本完成了,接下去就是編寫代碼了。導(dǎo)出本機(jī)函數(shù)的方法是在代碼中,使用[DllExport]特性來(lái)標(biāo)記靜態(tài)方法。"DllExport"特性支持自定義導(dǎo)出函數(shù)的名字、調(diào)用約定等。與["DllImport"]特性有些類似。注意,如果不指定調(diào)用約定,默認(rèn)導(dǎo)出的是"__cdecl",由于Windows API和易語(yǔ)言只支持stdcall方式導(dǎo)出,所以調(diào)用約定我們選擇"WINAPI"。DllExport也支持"MarshalAs"特性,可以用這個(gè)特性告訴.NET如何將.NET托管類型轉(zhuǎn)換為本機(jī)非托管類型。
C#代碼:
----------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace TextPreprocessAddon
{
?? ?public static class TextPreprocessAddon
?? ?{
?? ??? ?[DllExport("Init",CallingConvention.Winapi)]
?? ??? ? public static int Init ()
?? ??? ?{
?? ??? ??? ?return (1);
?? ??? ?}

?? ??? ?[DllExport("TextPreprocess",CallingConvention.Winapi)]
?? ??? ?public static int TextPreprocess (IntPtr oldTxtPtr,IntPtr newTxtPtr)
?? ??? ?{
?? ??? ??? ?try
?? ??? ??? ?{
?? ??? ??? ??? ?string oldText = Marshal.PtrToStringUni(oldTxtPtr);
?? ??? ??? ??? ?string newText = oldText.Replace("女孩","男孩");
?? ??? ??? ??? ?byte[] tempBytes = Encoding.Unicode.GetBytes(newText+"\0");
?? ??? ??? ??? ?Marshal.Copy(tempBytes,0,newTxtPtr,tempBytes.Length);
?? ??? ??? ??? ?return (newText.Length);
?? ??? ??? ?}
?? ??? ??? ?catch (Exception ex)
?? ??? ??? ?{
?? ??? ??? ??? ?return (0);
?? ??? ??? ?}
?? ??? ?}
?? ?}
}
----------

上面的代碼是用C#編寫的爭(zhēng)渡文本預(yù)處理插件,它可以將原始文本中的"女孩"替換成"男孩"。導(dǎo)出函數(shù)的實(shí)現(xiàn)過(guò)程如下:
使用[DllExport]特性來(lái)標(biāo)記靜態(tài)方法,指定導(dǎo)出函數(shù)的名稱和調(diào)用約定。
使用Marshal類中的方法來(lái)轉(zhuǎn)換指針和字符串類型,以及復(fù)制字節(jié)數(shù)組到內(nèi)存空間。
使用字符串類型中的方法來(lái)替換文本中的內(nèi)容,以及添加空字符。
返回新文本的長(zhǎng)度,或者在發(fā)生錯(cuò)誤時(shí)返回0。

然后編譯這個(gè)項(xiàng)目,可以在"release"文件夾中找到X86的文件夾,進(jìn)去就有導(dǎo)出的DLL了。

這樣,我們就用C#編寫了一個(gè)爭(zhēng)渡文本預(yù)處理插件,它可以將原始文本中的"女孩"替換成"男孩",并將修改后的文本送給讀屏朗讀。我們可以將這個(gè)DLL文件放在爭(zhēng)渡讀屏安裝目錄\addins\下,然后啟動(dòng)爭(zhēng)渡讀屏軟件,選擇我們的插件,就可以聽到效果了。

使用Python調(diào)用上面導(dǎo)出的DLL,實(shí)現(xiàn)Python調(diào)用C#代碼。

import ctypes
# 加載 dll(完整路徑)
my_lib = ctypes.WinDLL('d:\TextPreprocessAddon.dll')
# 定義函數(shù)原型
my_lib.Init.restype = ctypes.c_int
# 調(diào)用函數(shù)
int_result = my_lib.Init()
print("Result:", int_result)
# 調(diào)用 TextPreprocess 函數(shù),并獲取返回值
old_string = "這個(gè)小女孩長(zhǎng)得很漂亮。"
new_string = ctypes.create_unicode_buffer(65536) # 創(chuàng)建一個(gè) Unicode 緩沖區(qū)
result = my_lib.TextPreprocess(ctypes.c_wchar_p(old_string), new_string)
if result > 0:
?? ?print("New String:", new_string.value)
else:
?? ?print("Old String:", old_string)
input()

首先,我們需要導(dǎo)入ctypes模塊,它是Python的一個(gè)標(biāo)準(zhǔn)庫(kù),可以讓我們調(diào)用本機(jī)DLL中的函數(shù)。
然后,使用ctypes.WinDLL函數(shù),加載我們的DLL文件,注意要指定完整的路徑。這個(gè)函數(shù)會(huì)返回一個(gè)對(duì)象,我們把它賦值給my_lib變量,以便后面使用。
接著,使用my_lib.Init.restype屬性,定義Init函數(shù)的返回類型為整數(shù)類型。這樣我們就可以正確地接收Init函數(shù)的返回值了。
然后,直接調(diào)用my_lib.Init()函數(shù),它會(huì)返回一個(gè)整數(shù)值,表示當(dāng)前插件的版本號(hào)。我們把它賦值給int_result變量,并打印出來(lái)。
接著,我們準(zhǔn)備調(diào)用TextPreprocess函數(shù),它有兩個(gè)參數(shù):oldTxtPtr和newTxtPtr。oldTxtPtr是一個(gè)指向讀屏即將朗讀的原始文本的指針,newTxtPtr是一個(gè)指向插件修改后的新文本的指針。
為了傳遞這兩個(gè)參數(shù),我們需要做一些轉(zhuǎn)換。首先,我們定義一個(gè)字符串變量old_string,賦值為"這個(gè)小女孩長(zhǎng)得很漂亮。"。這是我們想要修改的原始文本。
然后,使用ctypes.c_wchar_p函數(shù),將old_string轉(zhuǎn)換為一個(gè)寬字符指針類型的對(duì)象。這樣就可以作為oldTxtPtr參數(shù)傳遞給TextPreprocess函數(shù)了。
接著,我們使用ctypes.create_unicode_buffer函數(shù),創(chuàng)建一個(gè)Unicode緩沖區(qū)類型的對(duì)象。這個(gè)函數(shù)需要一個(gè)參數(shù),表示緩沖區(qū)的大小。我們給它傳遞65536,表示緩沖區(qū)可以存儲(chǔ)65536個(gè)字節(jié)。這個(gè)緩沖區(qū)就可以作為newTxtPtr參數(shù)傳遞給TextPreprocess函數(shù)了。
然后,調(diào)用my_lib.TextPreprocess函數(shù),并傳遞oldTxtPtr和newTxtPtr兩個(gè)參數(shù)。這個(gè)函數(shù)會(huì)返回一個(gè)整數(shù)值,表示新文本的長(zhǎng)度。我們把它賦值給result變量,并判斷是否大于0。
如果result大于0,表示插件成功地修改了文本,并將新文本存儲(chǔ)在newTxtPtr指向的緩沖區(qū)中。我們可以使用new_string.value屬性,獲取緩沖區(qū)中的字符串值,并打印出來(lái)。
如果result等于0,表示插件沒(méi)有修改文本,或者發(fā)生了錯(cuò)誤。我們就直接打印old_string變量的值。

通過(guò)這段Python代碼,我們就可以看到爭(zhēng)渡文本預(yù)處理插件的效果了。它會(huì)將原始文本中的"女孩"替換成"男孩",并將修改后的文本送給讀屏朗讀。

你看,用C#導(dǎo)出本機(jī)DLL給Python是多么美好的事情啊!我們不僅可以利用C#的強(qiáng)大功能和豐富的庫(kù)來(lái)編寫更多的文本預(yù)處理效果,還可以讓Python等其他語(yǔ)言方便地調(diào)用我們的插件。這樣就實(shí)現(xiàn)了跨語(yǔ)言和跨平臺(tái)的互操作性。

這只是一個(gè)簡(jiǎn)單的導(dǎo)出函數(shù)例子。

"3f/DllExport"的最大優(yōu)點(diǎn)是可以讓C#也能導(dǎo)出本機(jī)風(fēng)格的函數(shù),供其他語(yǔ)言或平臺(tái)調(diào)用,從而實(shí)現(xiàn)跨語(yǔ)言和跨平臺(tái)的互操作性。這個(gè)庫(kù)的出現(xiàn),解決了C#的一大短板,就是不能像C++一樣生成普通的動(dòng)態(tài)鏈接庫(kù)。
????????"3f/DllExport"工具非常強(qiáng)大,支持與"ilmerge"配合使用,如果你的程序集引用了第三方庫(kù),它可以配合ILMerge將其合并為一個(gè)DLL。也支持風(fēng)送復(fù)雜類型,比如struct、array等。進(jìn)階玩法大家就自己去研究吧,本文就寫到這里。

參考資料:

https://github.com/3F/DllExport/
https://github.com/dotnet/ILMerge/
https://en.wikipedia.org/wiki/Assembly_(CLI)
https://en.wikipedia.org/wiki/Dynamic-link_library

http://www.risenshineclean.com/news/47248.html

相關(guān)文章:

  • 濟(jì)南免費(fèi)網(wǎng)站建設(shè)優(yōu)化網(wǎng)站管理
  • 響應(yīng)式網(wǎng)站是什么軟件做的app注冊(cè)拉新平臺(tái)
  • 企業(yè)網(wǎng)站建設(shè)哪家便宜游戲推廣渠道
  • 學(xué)院網(wǎng)站建設(shè)服務(wù)宗旨電商平臺(tái)排名
  • 南寧網(wǎng)絡(luò)推廣工作網(wǎng)絡(luò)優(yōu)化seo薪酬
  • 景安網(wǎng)站備案的服務(wù)碼韓國(guó)熱搜榜
  • 聽書網(wǎng)頁(yè)設(shè)計(jì)教程成都seo
  • 動(dòng)態(tài)網(wǎng)站開發(fā)技術(shù)哪幾種seo搜索引擎優(yōu)化入門
  • html網(wǎng)站開發(fā)心得體會(huì)查淘寶關(guān)鍵詞排名軟件
  • seo網(wǎng)站制作產(chǎn)品seo標(biāo)題是什么
  • 怎樣做微信小程序seo項(xiàng)目培訓(xùn)
  • 網(wǎng)站建設(shè)價(jià)格明細(xì)表和網(wǎng)站預(yù)算網(wǎng)站推廣常用方法
  • 網(wǎng)站代碼設(shè)計(jì)外貿(mào)網(wǎng)站如何推廣優(yōu)化
  • 網(wǎng)上服務(wù)平臺(tái)社保南昌seo報(bào)價(jià)
  • 提供網(wǎng)站建設(shè)公司哪家好ps培訓(xùn)
  • 網(wǎng)站怎么做seo、贛州網(wǎng)站建設(shè)公司
  • web前端只做網(wǎng)站么接推廣一般多少錢
  • 中組部 兩學(xué)一做 網(wǎng)站品牌策劃方案ppt
  • 低價(jià)服裝網(wǎng)站建設(shè)百度認(rèn)證官網(wǎng)申請(qǐng)
  • 可以看小視頻的瀏覽器南寧百度快速優(yōu)化
  • 網(wǎng)站前臺(tái)設(shè)計(jì)工具搜索引擎優(yōu)化的目標(biāo)
  • 速貝網(wǎng)站友情鏈接怎么做網(wǎng)站優(yōu)化排名怎么做
  • 建站平臺(tái)入口關(guān)鍵詞排名優(yōu)化怎么樣
  • 武昌做網(wǎng)站哪家專業(yè)競(jìng)價(jià)賬戶托管公司哪家好
  • 江油移動(dòng)網(wǎng)站建設(shè)推廣平臺(tái)
  • 上海房產(chǎn)做哪個(gè)網(wǎng)站好上海關(guān)鍵詞優(yōu)化推薦
  • 北京網(wǎng)站制作公司清遠(yuǎn)新聞?lì)^條新聞
  • 四川監(jiān)獄網(wǎng)站建設(shè)發(fā)布外鏈
  • 常用的網(wǎng)站推廣的方式方法搜索引擎優(yōu)化的基礎(chǔ)是什么
  • 用php做網(wǎng)站營(yíng)銷型網(wǎng)站的特點(diǎn)