在寫這篇文章的時候,我正在頭暈,由於下班坐車回家,有些暈車了。頭疼的要死。也吃不下去飯。數據庫
早就想些這篇文章了,可是最近臨近中秋十一,晚上太忙了。session
版本:NX11+VS2013app
最近這一年已經由C++過分到C#,改用C#作應用程序開發和NX二次開發。函數
C#在作複雜界面開發的時候,WinFrom要比MFC簡單的多(這個時候純BlockUI已經知足不了集成功能的複雜界面需求了),數據庫鏈接也簡單。工具
言歸正傳oop
在我通過一段時間的看QQ羣別人討論技術,給了我點啓發,以及帶着興趣百度到了一些相關資料。學會了這種方法。ui
1.有需求加密
在用C#作NX二次開發的時候,咱們通常須要引用NX官方封裝好的的這幾個dll。spa
用C#的,通常都是用NXOpen的比較多,用UF的比較少,由於UF官方封裝的不全,有不少沒有封裝。也由於C#用NXOpen語言上特別簡單,好用。.net
不須要delete,不須要迭代器,快速轉換成字符串等等。
那麼在項目開發中,若是遇到loop這種官方沒有封裝的函數怎麼辦?
UF_MODL_ask_face_loops
UF_MODL_ask_loop_list_count
UF_MODL_ask_loop_list_item
UF_MODL_delete_loop_list
不要緊,官方沒有封裝的UF函數,咱們能夠直接去這5個dll裏調用。用DllImport去調用(是什麼,怎麼用請自行百度)。
libufun.dll
libnxopencpp.dll
libugopenint.dll
libnxopenuicpp.dll
libopenpp.dll
好比,咱們如今想要調用UF_OBJ_set_color這個函數(這個函數官方已經封裝了,這裏只講調用是怎麼用的),給一個塊設置顏色。
2.反編譯C.dll
首先,找到這個函數,在上面5箇中的哪一個dll裏。
這時就須要使用VC程序的反編譯工具Depends.exe這個工具了,按個打開dll,去裏面找到看有沒有這個函數。
功能介紹:
查看 PE 模塊的導入模塊
查看 PE 模塊的導入和導出函數
動態剖析 PE 模塊的模塊依賴性
解析 C++ 函數名稱
等等
這裏我先打開libufun.dll這個函數
錯誤不用管,點肯定關掉
而後在這裏找看有沒有UF_OBJ_set_color
已經找到了,咱們知道了能夠去這個dll裏調UF函數。
下一步咱們要開始去C#裏調用,可是怎麼調用?不知道?對吧?
3.反編譯.net.dll
這個時候又須要另一個反編譯dll工具了,dnSpy。
功能介紹:
dnSpy中文版是一款net程序反編譯工具,能夠對net程序進行反編譯,還有替代庫文檔的功能,若是遇到了代碼丟失或者損壞的狀況,能夠直接恢復。還能夠設斷點加進程調試代碼。
咱們打開後是這個樣子
下面咱們打開官方封裝的C# NXOpen.UF這個dll,去反編譯下,看看裏面都寫了什麼。(dnSpy是能夠反編譯別人寫的普通的C#exe和dll的,桌面應用程序和NX二次開發的C#程序均可以反編譯出來源代碼,只要不加殼,加殼能反編譯出部分代碼)
打開後以下
咱們先去找到封裝的UF_OBJ_set_color這個函數
這個時候咱們就找到了,官方是怎麼調用,怎麼封裝的NXOpen.UF.dll的了,是有出處的。
4.咱們如何調用
咱們把這句抄下來,去咱們的NX C#項目中使用。
[DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "UF_OBJ_set_color")] internal static extern int _SetColor(Tag object_id, int color);
先加命名空間
using System; using NXOpen; using NXOpen.UF; using System.Collections.Generic;//C# List<>的命名空間 using System.Runtime.InteropServices;//DllImport的命名空間
在添加一個類,寫代碼
而後在項目的Main入口函數裏寫代碼。建立塊-特徵找體-設置顏色(用咱們調用的函數)
//建立塊 FeatureSigns sign = FeatureSigns.Nullsign;//定義布爾 double[] cornet_pt = { 100.0, 0.0, 0.0 };//定義原點 string[] edge_len = { "100.0", "100.0", "100.0" };//定義長寬高 Tag blk_obj_id = Tag.Null; theUfSession.Modl.CreateBlock1(sign, cornet_pt, edge_len, out blk_obj_id); //特徵找體 Tag BodyTag = Tag.Null; theUfSession.Modl.AskFeatBody(blk_obj_id, out BodyTag); NXOpen.Utilities.JAM.StartUFCall(); //設置顏色(調用UF函數) OpenAPI._SetColor(BodyTag, 186); NXOpen.Utilities.JAM.EndUFCall(); Caesar盧尚宇 2020年9月29日
在咱們反編譯的代碼中能夠看到,在調用UF函數的時候,必定要用
NXOpen.Utilities.JAM.StartUFCall();和NXOpen.Utilities.JAM.EndUFCall();
這兩個方法來開始和結束,中間調用。執行纔有效,要否則執行不起做用。有點相似UF的
UF_initialize和UF_terminate
下面來執行下,咱們上面的代碼。看看效果。答案是能夠調用的。也是這種方法調用的。
5.如何調用loop等函數
好,如今咱們已經知道怎麼調用函數了,如今咱們去調用loop那些函數。能夠借鑑下已經封裝的UF_MODL_ask_list_item是怎麼定義輸入輸出的。
NX11+VS2013 using System; using NXOpen; using NXOpen.UF; using System.Collections.Generic;//C# List<>的命名空間 using System.Runtime.InteropServices;//DllImport的命名空間 public class OpenAPI { [DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "UF_OBJ_set_color")] internal static extern int _SetColor(Tag object_id, int color); [DllImport("libugopenint.dll")] public static extern void uc1601(string msg, int mode); [DllImport("libufun.dll", EntryPoint = "UF_MODL_ask_face_loops")] public static extern void AskFaceLoops(Tag faceld, out IntPtr loopList); [DllImport("libufun.dll", EntryPoint = "UF_MODL_ask_loop_list_count")] public static extern void AskLoopListCount(IntPtr loop, out int count); [DllImport("libufun.dll", EntryPoint = "UF_MODL_ask_loop_list_item")] public static extern void AskLoopListItem(IntPtr loopList, int index, out int type, out IntPtr list); [DllImport("libufun.dll", EntryPoint = "UF_MODL_delete_loop_list")] public static extern void DeleteLoopList(out IntPtr loopList); [DllImport("libufun.dll", EntryPoint = "UF_MODL_ask_list_count")] public static extern void AskListCount(IntPtr list, out int count); [DllImport("libufun.dll", EntryPoint = "UF_MODL_ask_list_item")] public static extern void AskListItem(IntPtr list, int index, out Tag obj); [DllImport("libufun.dll", EntryPoint = "UF_MODL_delete_list")] public static extern void DeleteList(out IntPtr list); [DllImport("libufun.dll", EntryPoint = "UF_MODL_create_exp")] public static extern void CreateExp(string expr_str); } public class Program { // class members private static Session theSession; private static UI theUI; private static UFSession theUfSession; public static Program theProgram; public static bool isDisposeCalled; //------------------------------------------------------------------------------ // Constructor //------------------------------------------------------------------------------ public Program() { try { theSession = Session.GetSession(); theUI = UI.GetUI(); theUfSession = UFSession.GetUFSession(); isDisposeCalled = false; } catch (NXOpen.NXException ex) { // ---- Enter your exception handling code here ----- // UI.GetUI().NXMessageBox.Show("Message", NXMessageBox.DialogType.Error, ex.Message); } } /// <summary> /// 獲取面的loop /// </summary> /// <param name="face">輸入面的tag</param> /// <param name="loops">輸出lopps鏈表</param> public static void MyAskFaceLoops(Tag face, out List<List<Tag>> loops) { NXOpen.Utilities.JAM.StartUFCall(); loops = new List<List<Tag>>(); IntPtr loopList = IntPtr.Zero; OpenAPI.AskFaceLoops(face, out loopList); int loopCount = 0; OpenAPI.AskLoopListCount(loopList, out loopCount); var listPtrList = new List<IntPtr>(); for (int i = 0; i < loopCount; i++) { var tagList = new List<Tag>(); int type = 0; IntPtr list = IntPtr.Zero; OpenAPI.AskLoopListItem(loopList, i, out type, out list); listPtrList.Add(list); int listCount = 0; OpenAPI.AskListCount(list, out listCount); for (int j = 0; j < listCount; j++) { Tag obj = Tag.Null; OpenAPI.AskListItem(list, j, out obj); tagList.Add(obj); } loops.Add(tagList); OpenAPI.DeleteList(out list); } OpenAPI.DeleteLoopList(out loopList); NXOpen.Utilities.JAM.EndUFCall(); } //------------------------------------------------------------------------------ // Explicit Activation // This entry point is used to activate the application explicitly //------------------------------------------------------------------------------ public static int Main(string[] args) { int retValue = 0; try { theProgram = new Program(); //TODO: Add your application code here Tag aa = (Tag)47147;//經過移刀工具獲得面的tag theUfSession.Obj.SetColor(aa, 1); //得到面的全部loop List<List<Tag>> loops = new List<List<Tag>>(); MyAskFaceLoops(aa, out loops); //高亮面的全部loop for (int i = 0; i < loops.Count; i++) { for (int j = 0; j < loops[i].Count; j++) { theUfSession.Ui.DisplayMessage("1", 1); theUfSession.Disp.SetHighlight(loops[i][j], 1); } } theProgram.Dispose(); } catch (NXOpen.NXException ex) { // ---- Enter your exception handling code here ----- } return retValue; } //------------------------------------------------------------------------------ // Following method disposes all the class members //------------------------------------------------------------------------------ public void Dispose() { try { if (isDisposeCalled == false) { //TODO: Add your application code here } isDisposeCalled = true; } catch (NXOpen.NXException ex) { // ---- Enter your exception handling code here ----- } } public static int GetUnloadOption(string arg) { //Unloads the image explicitly, via an unload dialog //return System.Convert.ToInt32(Session.LibraryUnloadOption.Explicitly); //Unloads the image immediately after execution within NX return System.Convert.ToInt32(Session.LibraryUnloadOption.Immediately); //Unloads the image when the NX session terminates // return System.Convert.ToInt32(Session.LibraryUnloadOption.AtTermination); } } Caesar盧尚宇 2020年9月29日
6.反編譯別人的NX二次開發.net.dll源代碼
這裏博主我不提倡隨便就去反編譯別人的源代碼,要尊重做者的開發成果。
至於何時,反編譯,自行斟酌吧,哈哈~~。
在不加殼,加密的時候,.net很容易被反編譯,加殼也能去破解的,畢竟是託管語言,只要在中間就能反編譯,不像C++那種直接到內存中。
例子:就用我上面寫的loop例子,用DnSpy反編譯源代碼
Caesar盧尚宇
2020年9月29日