Python具有豐富的功能庫,運行于多種平臺,可移植性好,使用簡單,雖然python主要運行于桌面系統,但通過對python代碼的部分修改,已經將python解釋器成功編譯到windows 10 uwp平臺,使得在UWP應用中可以使用python腳本。由于windows 10的限制,一些python擴展庫無法使用,這些擴展庫主要涉及到進程和管道相關的功能,對應的庫有:_winapi asyncio _overlapped_ctypes _multiprocessing _msi SubPRocess。
這里是一個運行于windows 10的python解釋器的例子,由于主要是為了說明如何初始化python解釋器,運行python腳本,例子中的界面比較簡單,一個輸入欄用于輸入python腳,一個輸出欄用于顯示運行的結果。
打開vs2015,創建一個c# universal工程,如下圖:
添加引用,Star_csharp和libstarcore
添加python相關的庫和文件,libstar_python34.pyd,python34.dll,python3.4.zip。python3.4.zip為python的擴展庫,可以根據實際需要裁剪。
設置python文件的屬性
/
例子基于CLE開發,首先需要初始化CLE,初始化CLE有兩種方式,直接在界面線程中初始化,此時CLE運行于界面線程,python解釋器同樣運行于界面線程,python代碼也在界面線程中運行;另外一種方式是創建一個獨立的線程初始化CLE,python解釋器運行在初始化CLE的線程中,這種方式的好處是python腳本的執行不會影響界面刷新,但是從界面線程調用CLE相關的函數,或者執行python腳本,需要進行加鎖操作,此外該線程需要維護CLE的消息循環。
StarCoreFactoryInit.Init(this);StarCoreFactory starcore = StarCoreFactory.GetFactory();StarServiceClass Service = (StarServiceClass)starcore._InitSimple("test", "123", 0, 0, null);SrvGroup = (StarSrvGroupClass)Service._Get("_ServiceGroup");bool Result = SrvGroup._InitRaw("python34", Service);StarObjectClass python = Service._ImportRawContext("python", "", false, "");2.2 在獨立線程中初始化CLE和python
使用BackgroundWorker創建線程,在線程中初始化CLE和pythonbackroungServer = new BackgroundWorker();backroungServer.DoWork += new DoWorkEventHandler(backroungServer_DoWork);backroungServer.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backroungServer_Complete);backroungServer.ProgressChanged += OnServerProgressChanged;backroungServer.WorkerReportsProgress = true;backroungServer.RunWorkerAsync();private void backroungServer_DoWork(object sender, DoWorkEventArgs e){ StarCoreFactoryInit.Init(this); StarCoreFactory starcore = StarCoreFactory.GetFactory(); StarServiceClass Service = (StarServiceClass)starcore._InitSimple("test", "123", 0, 0, null); SrvGroup = (StarSrvGroupClass)Service._Get("_ServiceGroup"); bool Result = SrvGroup._InitRaw("python34", Service); StarObjectClass python = Service._ImportRawContext("python", "", false, ""); //---enter message loop while (true) { while (starcore._SRPDispatch(false) == true) ; starcore._SRPUnLock(); Task.Delay(10).Wait(); starcore._SRPLock(); }}private void OnServerProgressChanged(object sender, ProgressChangedEventArgs e){}private void backroungServer_Complete(object sender, RunWorkerCompletedEventArgs e){}3. 捕獲python腳本的輸出
為了捕獲python腳本的輸出結果,需要注冊CLE的回調函數,實現StarMsgCallBackInterface接口,在回調函數中,將輸出結果顯示到文本框中starcore._RegMsgCallBack_P(new StarMsgCallBackInterface(delegate (int ServiceGroupID, int uMes, object wParam, object lParam){ if (uMes == starcore._Getint("MSG_DISPMSG") || uMes == starcore._Getint("MSG_DISPLUAMSG")) { textBlock1.Text = textBlock1.Text + "/n" + (string)wParam; } return null;}));4. 執行python腳本
4.1編譯不執行
可以只編譯腳本,不執行,此時檢查腳本中的語法錯誤。編譯腳本需要調用CLE的函數_PreCompile。該函數返回一個object[]數組,如果object[0]是true,則成功編譯;如果為false, 并且object[1]的長度為0,表示輸入腳本不完整;否則object[1]返回編譯錯誤。
private void button_Click(object sender, RoutedEventArgs e){ string script = textBox.Text; if (script.Length == 0) return;#if CLETHREAD starcore._SRPLock();#endif object[] result = SrvGroup._PreCompile("python", script+"/n");#if CLETHREAD starcore._SRPUnLock();#endif if ((bool)result[0] == true) textBlock1.Text = "success"; else { if (((string)result[1]).Length == 0) textBlock1.Text = "More Input"; else textBlock1.Text = (string)result[1]; }}4.2直接執行腳本
調用CLE的函數_RunScript執行python腳本。腳本的輸出會被之前設置的回調函數捕獲,顯示到輸出窗口中。
private void button1_Click(object sender, RoutedEventArgs e){ textBlock1.Text = ""; string script = textBox.Text; if (script.Length == 0) return;#if CLETHREAD starcore._SRPLock();#endif Service._RunScript("python", script + "/n", "", "");#if CLETHREAD starcore._SRPUnLock();#endif}5. 支持arm的版本
如果需要運行在window 10 mobile設備上,需要編譯arm的版本,此時要將引用,python相關的文件替換為arm對應的文件。
首先刪除工程中的上述文件,然后再添加,步驟參考步驟1,只不過在選擇文件的時候,選取arm目錄下的文件
6. 結束語
本例子實現了一個可運行于windows 10 uwp平臺的python解釋器,代碼非常簡單。可以參考本文中的方法,在UWP應用中使用python腳本語言。編譯運行本文中的例子需要CLE(http://www.srplab.com/data/starcore_for_winuap.2.5.1.zip),下載之后解壓,與例子放在統一目錄,如下:
示例代碼下載
新聞熱點
疑難解答