三部曲:
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
在看了三部曲1之后,大家应该对C#怎么用DllImport调用UF函数有了简单的认识,但是不一定能找到窍门。
这一篇就是来讲使用方法和窍门的。我个人觉得调哪个函数不难,难在要定义那个函数的输入输出的类型。
有的时候类型定义的不对,就报错。怎么把类型定义对,就得找窍门。
1.还是有需求
因为C#中并没有封装tag和handle互相转换的函数,这里我们以它为主线,展开研究。
UF_TAG_ask_handle_from_tag
UF_TAG_ask_tag_of_handle
我们看这两个函数
这里面tag输入类型和定义,直接用C#的Tag就行,char*的输入参数也好定义,用C#的string类型。
唯独这个输出char**这个函数,我一开始一直找不到输出类型应该怎么定义,定义out string就报错。
一直不断的试,还是不行,最后还是去反编译查看官方dll中是怎么封装定义的。
2.学习方法
首先我们找到UF函数中含有输出带char**的简单函数,后来我找到了这个函数UF_MODL_ask_exp_tag_string,
输出类型是一样的。
下面我们去反编译dll,去查看官方是怎么定义那个类型的。
官方都是按照这种格式封装的,我们也仿照它这种格式书写。把代码抄过来
将代码函数和变量名换成UF_TAG_ask_handle_from_tag,编译发现报错了。
这个问题需要改一下设置,项目属性-生成-允许不安全代码
在编译上面的报错问题就没有了,又出现一个新的问题,这是因为我们还没有为out string去赋值。
下面介绍这个函数里面该怎么写代码
3.重点
仔细研究下,官方这里都用了哪些函数方法,点进去函数查看定义。
1.这两个方法成对出现。NXOpen.Utilities.JAM.StartUFCall(); NXOpen.Utilities.JAM.EndUFCall();
2.然后调用了上面定义的_AskExpTagString方法,输入一个Tag,输出的是一个IntPtr类型。
3.最后调用了JAM.ToStringFromLocale 将IntPtr类型转换成了string类型,然后输出。
4.打印错误这个地方就不介绍了,自己去看吧。throw Util.CreateException(num);
4.我们的代码
依照这个步骤,我们去把UF_TAG_ask_handle_from_tag的转换代码写出来。这就是学习方法
public class OpenAPI { [DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "UF_TAG_ask_handle_from_tag")] internal static extern int _TagToHandle(Tag object_tag, out IntPtr _string); public unsafe static void TagToHandle(Tag object_tag, out string _string) { NXOpen.Utilities.JAM.StartUFCall(); IntPtr s; OpenAPI._TagToHandle(object_tag, out s); _string = NXOpen.Utilities.JAM.ToStringFromLocale(s, true); NXOpen.Utilities.JAM.EndUFCall(); } }
这个就写完了,直接去调用就可以了。以后有不会定义输入输出类型的函数,就用这种方法去查看怎么定义,怎么转换。
下面在把UF_TAG_ask_tag_of_handle也定义一下,这个比较简单,输入一个字符串,返回值为Tag就行了。
[DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "UF_TAG_ask_tag_of_handle")] internal static extern Tag _HandleToTag(string object_handle); public unsafe static Tag HandleToTag(string object_handle) { NXOpen.Utilities.JAM.StartUFCall(); Tag aa = OpenAPI._HandleToTag(object_handle); return aa; NXOpen.Utilities.JAM.EndUFCall(); }
例子代码
using System; using NXOpen; using NXOpen.UF; using NXOpen.Utilities; using System.Runtime.InteropServices;//DllImport的命名空间 public class OpenAPI { [DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "UF_TAG_ask_handle_from_tag")] internal static extern int _TagToHandle(Tag object_tag, out IntPtr _string); public unsafe static void TagToHandle(Tag object_tag, out string _string) { NXOpen.Utilities.JAM.StartUFCall(); IntPtr s; OpenAPI._TagToHandle(object_tag, out s); _string = NXOpen.Utilities.JAM.ToStringFromLocale(s, true); NXOpen.Utilities.JAM.EndUFCall(); } [DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "UF_TAG_ask_tag_of_handle")] internal static extern Tag _HandleToTag(string object_handle); public unsafe static Tag HandleToTag(string object_handle) { NXOpen.Utilities.JAM.StartUFCall(); Tag aa = OpenAPI._HandleToTag(object_handle); return aa; NXOpen.Utilities.JAM.EndUFCall(); } } 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); } } //------------------------------------------------------------------------------ // 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设置颜色 Tag aa = (Tag)49129; theUfSession.Obj.SetColor(aa, 186); //tag转handle string bq = ""; OpenAPI.TagToHandle(aa, out bq); //handle转tag Tag ww = OpenAPI.HandleToTag(bq); //打印 theUfSession.Ui.DisplayMessage(bq, 1); theUfSession.Ui.DisplayMessage(ww.ToString(), 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月30日
函数调用,例子演示。
5.附件参考
最后在附加几个我写好的调用函数,作为学习参考,你们可以去反编译dll看官方是怎么定义sbyte*和out IntPtr类型,转换的。
public class OpenAPI { [DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "UF_MODL_ask_exp_tag_string")] internal static extern int _AskExpTagString(Tag expression_tag, out IntPtr _string); public unsafe static void AskExpTagString(Tag expression_tag, out string exp_defn) { NXOpen.Utilities.JAM.StartUFCall(); IntPtr s; OpenAPI._AskExpTagString(expression_tag, out s); exp_defn = NXOpen.Utilities.JAM.ToStringFromLocale(s, true); NXOpen.Utilities.JAM.EndUFCall(); } [DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "UF_TAG_ask_handle_from_tag")] internal static extern void _TagToHandle(Tag object_tag, out IntPtr _string); public unsafe static void TagToHandle(Tag object_tag, out string exp_defn) { NXOpen.Utilities.JAM.StartUFCall(); IntPtr s; OpenAPI._TagToHandle(object_tag,out s); exp_defn = NXOpen.Utilities.JAM.ToStringFromLocale(s, true); NXOpen.Utilities.JAM.EndUFCall(); } [DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "UF_TAG_ask_tag_of_handle")] internal static extern Tag _HandleToTag(string object_handle); public unsafe static Tag HandleToTag(string object_handle) { NXOpen.Utilities.JAM.StartUFCall(); Tag aa = OpenAPI._HandleToTag(object_handle); return aa; NXOpen.Utilities.JAM.EndUFCall(); } [DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "UF_MODL_ask_exp")] internal unsafe static extern int _AskExp(IntPtr exp_name, sbyte* exp_defn); public unsafe static void AskExp(string exp_name, out string exp_defn) { NXOpen.Utilities.JAM.StartUFCall(); sbyte* ptr = stackalloc sbyte[3073]; IntPtr intPtr = NXOpen.Utilities.JAM.ToLocaleString(exp_name); OpenAPI._AskExp(intPtr, ptr); string text = NXOpen.Utilities.JAM.ToStringFromLocale((IntPtr)((void*)ptr), false); exp_defn = text; NXOpen.Utilities.JAM.EndUFCall(); } } Caesar卢尚宇 2020年9月30日
下一篇,三部曲3,我将要写怎么反编译调用"内部函数"
Caesar卢尚宇
2020年9月30日