在X 中編譯並執行C 指令碼

2021-09-05 22:33:50 字數 2431 閱讀 9681

發生了什麼?

這是件非常有趣的事情。我們現在可以在x++中編譯並執行c#指令碼。請看下面的x++**:

static void runcsharp(args _args)

" + "}"

#endmacro

;runner = new sunnychen.csharpscript.scriptrunner();

// prepares the parameters

scriptargs = new system.collections.arraylist();

scriptargs.add(10);

scriptargs.add(20);

// runs the script

if (runner.compile(#sourcescript))

else}}

執行完上面這段job程式,dynamics ax就會編譯#sourcescript巨集中定義好的c#指令碼,然後執行指令碼程式,並彈出了乙個infolog,上面顯示了計算結果:30。如下:

這是如何實現的?

如果你直接將上面的job匯入到aot裡去執行,那麼在編譯階段就會出錯,原因是你的dynamics ax根本無法找到sunnychen.csharpscript.scriptrunner這一型別。這個型別是我自己編寫的乙個.net的類,它使用了.net提供的codedom(code document object model)和reflection的機制實現c#指令碼的編譯和執行。我使用visual studio建立了乙個名為sunnychen.csharpscript的class library專案,然後往該專案中新增了這個類:

public class scriptrunner

else

return false;}}

catch (exception e)

}public stringcollection compileerros

}public arraylist run(arraylist args)

}foreach (var methodinfo in entrytype.getmethods(bindingflags.public |

bindingflags.static))

}type returntype = entrypoint.returntype;

parameterinfo parameters = entrypoint.getparameters();

if (returntype.equals(typeof(arraylist)) &&

parameters != null &&

parameters.count() == 1 &&

parameters[0].parametertype.equals(typeof(arraylist))));}

}catch(exception e)

eventlog.writeentry("csharpscript", sb.tostring(), eventlogentrytype.error);

throw;

}return ret;}}

在編譯選項中,需要對sunnychen.csharpscript專案進行數字簽名:

簽名完,編譯好以後,就將編譯出來的sunnychen.csharpscript.dll安裝到gac裡。方法是,在run裡輸入c:\windows\assembly,然後將這個dll拖拽到開啟的視窗中即可。

最後一步,將sunnychen.csharscript新增到dynamics ax的aot\references中,再回過頭來編譯上面的job。此時job能夠順利通過編譯並正確執行。

這樣做有什麼實際應用?

看上去這只是乙個噱頭,就是一種技術把戲,貌似在實際應用中沒什麼特別的用處。其實,這個技術可以幫我們解決這樣的場景:比如產品銷售時,優惠策略的動態配置。針對不同的產品、分類或者地域,產品**優惠的計算是非常複雜的,通常情況下我們也只能在系統設計的時候引入常見的幾種**優惠方式,或者更靈活一點,提供介面,便於今後二次開發進行擴充套件。然而這兩種方式都是需要軟體開發人員介入的,而不是面向終端使用者的。當使用者打算修改優惠策略時,就不得不去做系統擴充套件,甚至改動現有的邏輯。

我做了乙個原型,就是根據custtable中所有客戶的成交交易總額進行折扣計算。比如當使用者交易額超過2000元,則給8.7折優惠,如果沒有超過,則給9.5折優惠,從而在base amount的基礎上,計算出折扣金額和最後應付款額。請看:

在上面的form中,我定義了折扣計算的**,這個**可以包含基於result(折扣額)和totalamount(總交易額)計算的c#**。**可以包含任何c#支援的語法。當然,終端使用者對程式設計肯定是一竅不通的,不過在這裡輸入幾個if...else或者switch...case,應該還是問題不大的。下圖就是執行時的結果:

源**

lua指令碼載入並編譯外部的lua執行指令碼

封裝公用的函式檔案 lua列印table資料 function luaprinttable t,name local spaceadd 4local function gettablestr t,name,space local str string.format s s n return str ...

在DOS視窗編譯並執行 cs檔案

1 如編譯 a.cs 檔案,則在 dos視窗輸入如下命令 以上命令將產生 a.cs 檔案的應用程式 a.exe 然後輸入命令 a.exe 就可以執行 a.cs 檔案。2 如a.cs 檔案的執行需要呼叫乙個 b.cs 檔案,則需要先將 b.cs 檔案編譯為 dll 檔案,命令如下 再輸入如下命令生成 ...

在Linux中使用終端編譯並執行 c和 cpp檔案

首先要保證系統中安裝了c語言和c 對應的編譯器 gcc c g c 1 c檔案hello.c 如下 include int main 在當前路徑下編譯.c檔案 gcc o hello hello.c 編譯完成後可以看到在和hello.c相同目錄下有乙個hello的可執行檔案。在當前路徑下執行編譯後的...