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

版本: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日

NX二次开发-C#使用DllImport调用libufun.dll里的UF函数(反编译.net.dll)调用loop等UF函数的更多相关文章

  1. NX二次开发-BlockUI对话框嵌套MFC对话框制作进度条

    半年前在一些QQ群看到有大神NX二次开发做出了进度条,那个时候我还不会弄,也不知道怎么弄得,后来断断续续得研究了一下,直到今天我把它做出来了.内心还是很喜悦的!回想自己这两年当初从没公司肯给我做NX二 ...

  2. NX二次开发-UDO用户自定义对象(UFUN)【持续完善】

    每当提起UDO总是会让我想起大专毕业那会失业找工作,后来有个宝贵机会去了软件公司上班,拿到了我人生中的第一个NX二次开发项目,一个关于测量汽车前后左右摄像头的项目.当时那个项目就用到了UDO,对于只看 ...

  3. NX二次开发-UFUN将工程图转成CGM和PDF文件UF_CGM_export_cgm

    文章转载自唐康林NX二次开发论坛,原文出处: http://www.nxopen.cn/thread-126-1-1.html 刚才有同学问到这个问题,如果是用NXOpen来做,直接录制一下就可以了: ...

  4. NX二次开发-UFUN获取NX系统默认导出CGM的选项设置UF_CGM_ask_default_export_options

    文章转载自唐康林NX二次开发论坛,原文出处: http://www.nxopen.cn/thread-126-1-1.html 刚才有同学问到这个问题,如果是用NXOpen来做,直接录制一下就可以了: ...

  5. NX二次开发-UFUN获取当前导出CGM选项设置UF_CGM_ask_session_export_options

    文章转载自唐康林NX二次开发论坛,原文出处: http://www.nxopen.cn/thread-126-1-1.html 刚才有同学问到这个问题,如果是用NXOpen来做,直接录制一下就可以了: ...

  6. NX二次开发-UFUN修改当前导出CGM文件选项设置UF_CGM_set_session_export_options

    文章转载自唐康林NX二次开发论坛,原文出处: http://www.nxopen.cn/thread-126-1-1.html 刚才有同学问到这个问题,如果是用NXOpen来做,直接录制一下就可以了: ...

  7. 【NX二次开发】按层查找工作部件中的对象 UF_LAYER_cycle_by_layer

    第一次调用 :返回第一个启用层中的第一个对象. 第二次调用 :返回下一个已启用层中的下一个对象. 最后一次调用:当所有对象都被耗尽时,将返回object_tag = NULL_TAG. 在循环数据库时 ...

  8. 【NX二次开发】大开眼界,DLL还可以这么调!

    NX二次开发应用程序有交互式.批处理和远程3中模式.交互模式的应用程序(.dll)在NX界面环境下运行.dll以动态链接库的方式被加载到NX的进程空间中.dll可以通过下列几种方式执行. 1.直接激活 ...

  9. NX二次开发-使用NXOPEN C++向导模板做二次开发

    版本 NX9+VS2012 1.怎么往VS软件里添加VC,C#,VB向导模板 先到NX安装目录下UGOPEN文件夹里找到这三个文件夹 拷贝到VS的安装目录下 这里有几个注意事项,VS2017,VS20 ...

随机推荐

  1. 状态压缩动态规划(状压DP)详解

    0 引子 不要999,也不要888,只要288,只要288,状压DP带回家.你买不了上当,买不了欺骗.它可以当搜索,也可以卡常数,还可以装B,方式多样,随心搭配,自由多变,一定符合你的口味! 在计算机 ...

  2. py_正则表达式练习

    正则表达式: #正则表达式 #键盘数字6上的符号,^表示行的开始,$ 表示行的结束 #test = "tm queal Tomorrow Moon" ''' ^tm #匹配tm开头 ...

  3. Qt 最简单的多线程方法QtConcurrent::run()

    Qt 最简单的多线程方法QtConcurrent::run()(转载) 最近编写了一个软件,没有考虑多线程的问题,编好以后,软件在执行计算的时候,鼠标响应有时候会延迟,但是完全能用,考虑到后续随着计算 ...

  4. vs使用fscanf和fprintf错误警告处理

    严重性代码说明项目文件行 禁止显示状态错误 C4996 fopen('fscanf'.strcmp):This function or variable may be unsafe. 最全解决办法(转 ...

  5. Javascript数组与函数初识

    1 - 数组 1.1 数组的概念 数组可以把一组相关的数据一起存放,并提供方便的访问(获取)方式. 数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素.数组是一种将一组数 ...

  6. WPF新手快速入门系列 2.绑定

    [概要] 上一章讲了布局,按照市面上的书籍每一本讲的顺序都不一样,本系列是希望大家能快速上手去应对工作需要,所以本章就直接开始讲绑定. 如有学习过程中想交流学习.疑惑解答可以来此QQ群交流:58074 ...

  7. 关于windou环境下使用http或者ftp搭建网络hu共享

    第一步 右键此电脑进入控制面 第二步:进入程序点击启用或关闭windous功能 第三步进入服务开启界面 点击让windows更新为你下载文件,并保存更改完,然后关闭 四:邮件我的电脑进入管理 四右键添 ...

  8. js判断传递参数的的类型,并返回

    function   type(target) { var templet  ={ "[object Array]" :  "arry"; "[obj ...

  9. 【Maven】Mac操作系统下安装配置maven环境变量

    1.下载maven 下载地址:http://maven.apache.org/download.cgi 2.解压设置maven本地地址解压后 我放在 /Users/david/developer/ap ...

  10. 4-6年经验左右、优秀的 Java 程序员应该具备的技能

    4-6年经验左右.优秀的 Java 程序员应该具备的技能有哪些,按“专业技能”和“项目”两块,包括但不限于以下内容. 专业节能方面 基础:JDK 常用类的原理.源码.使用场景. 设计模式:常用几种的原 ...