zoukankan      html  css  js  c++  java
  • NX二次开发-C#使用DllImport调用libufun.dll里的UF函数(反编译.net.dll)调用loop等UF函数(三部曲1)

    在写这篇文章的时候,我正在头晕,因为下班坐车回家,有些晕车了。头疼的要死。也吃不下去饭。

    早就想些这篇文章了,但是最近临近中秋十一,晚上太忙了。

    NX二次开发-C#使用DllImport调用libufun.dll里的UF函数(反编译.net.dll)调用loop等UF函数(三部曲1)

    NX二次开发-C#使用DllImport调用libufun.dll里的UF函数学习方法及tag转handle例子(三部曲2)

    NX二次开发-C#使用DllImport调用libugui.dll里的内部函数自动将NX标题设置为prt路径例子(三部曲3)

    版本:NX11+VS2013

    最近这一年已经由C++过度到C#,改用C#做应用程序开发和NX二次开发。

    C#在做复杂界面开发的时候,WinFrom要比MFC简单的多(这个时候纯BlockUI已经满足不了集成功能的复杂界面需求了),数据库连接也简单。

    言归正传

    在我经过一段时间的看QQ群别人讨论技术,给了我点启发,以及带着兴趣百度到了一些相关资料。学会了这种方法。

    1.有需求

    在用C#做NX二次开发的时候,我们一般需要引用NX官方封装好的的这几个dll。

     用C#的,一般都是用NXOpen的比较多,用UF的比较少,因为UF官方封装的不全,有很多没有封装。也因为C#用NXOpen语言上特别简单,好用。

    不需要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日

  • 相关阅读:
    使用Git遇到的问题及解决方案(初级)
    巧记前端易混淆的英文语法
    编程助手JavaScript学习库-DOM笔记
    编程助手JavaScript学习库-面向对象编程笔记
    JS原始类型:数值的运用技巧
    这题目有毒之干不过codewars的OJ系统(一)
    Javascript运算符进阶指南
    Qt:During startup program exited with code 0xc0000135
    QT 消息处理机制
    Windows环境 和 Linux环境下搭建Qt开发环境
  • 原文地址:https://www.cnblogs.com/nxopen2018/p/13751886.html
Copyright © 2011-2022 走看看