none
c# 怎么调用tcl/tk script RRS feed

答案

  • 参考这里

    https://social.msdn.microsoft.com/Forums/en-US/eda39fb3-665c-42a1-9247-4e27adede528/tcltk-interpreter-in-c?forum=csharpgeneral

    using System.Runtime.InteropServices;
    using System;
    
    namespace TclWrap {
        public class TclAPI {
             [DllImport("tcl84.DLL")]
             public static extern IntPtr Tcl_CreateInterp();
             [DllImport("tcl84.Dll")]
             public static extern int Tcl_Eval(IntPtr interp,string skript);
             [DllImport("tcl84.Dll")]
             public static extern IntPtr Tcl_GetObjResult(IntPtr interp);
             [DllImport("tcl84.Dll")]
             unsafe public static extern char* Tcl_GetStringFromObj(IntPtr tclObj,IntPtr length);
        }
        public class TclInterpreter {
            private IntPtr interp;
            public TclInterpreter() {
                interp = TclAPI.Tcl_CreateInterp();
                if (interp == IntPtr.Zero) {
                    throw new SystemException("can not initialize Tcl interpreter");
                }
            }
            public int evalScript(string script) {
                return TclAPI.Tcl_Eval(interp,script);        
            }
            unsafe public string Result {
                get { 
                    IntPtr obj = TclAPI.Tcl_GetObjResult(interp);
                    if (obj == IntPtr.Zero) {
                        return "";
                    } else {
                        return Marshal.PtrToStringAnsi((IntPtr)TclAPI.Tcl_GetStringFromObj(obj,IntPtr.Zero));
                    }
                }
            }
        }
    }

    Using of it in C#

    TclInterpreter interp = new TclInterpreter(); string result; if (interp.evalScript("set a 3; {exp $a + 2}") != 0) { result = interp.Result; }


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    • 已标记为答案 zoromini 2016年10月20日 6:39
    • 取消答案标记 zoromini 2016年10月20日 7:41
    • 已标记为答案 zoromini 2016年10月21日 1:09
    2016年10月20日 2:47
  • 根据错误,你应该检查

    unsafe public static extern char* Tcl_GetStringFromObj(IntPtr tclObj,IntPtr length);

    DllImport 这些函数的签名对不对。

    应该是签名你弄错了.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    • 已标记为答案 zoromini 2016年10月20日 6:38
    • 取消答案标记 zoromini 2016年10月20日 7:41
    • 已标记为答案 zoromini 2016年10月21日 1:09
    2016年10月20日 5:38
    版主
  • [DllImport("Dll.dll")]

    改为[DllImport("Dll.dll", CallingConvention=CallingConvention.Cdecl)]
    DllImport的CallingConvention的属性,默认值是CallingCovention.Stdcall,  此处更改成Cdecl(c/c++默认调用方式)就可以了。
    • 已标记为答案 zoromini 2016年10月21日 1:09
    2016年10月20日 6:38

全部回复

  • 参考这里

    https://social.msdn.microsoft.com/Forums/en-US/eda39fb3-665c-42a1-9247-4e27adede528/tcltk-interpreter-in-c?forum=csharpgeneral

    using System.Runtime.InteropServices;
    using System;
    
    namespace TclWrap {
        public class TclAPI {
             [DllImport("tcl84.DLL")]
             public static extern IntPtr Tcl_CreateInterp();
             [DllImport("tcl84.Dll")]
             public static extern int Tcl_Eval(IntPtr interp,string skript);
             [DllImport("tcl84.Dll")]
             public static extern IntPtr Tcl_GetObjResult(IntPtr interp);
             [DllImport("tcl84.Dll")]
             unsafe public static extern char* Tcl_GetStringFromObj(IntPtr tclObj,IntPtr length);
        }
        public class TclInterpreter {
            private IntPtr interp;
            public TclInterpreter() {
                interp = TclAPI.Tcl_CreateInterp();
                if (interp == IntPtr.Zero) {
                    throw new SystemException("can not initialize Tcl interpreter");
                }
            }
            public int evalScript(string script) {
                return TclAPI.Tcl_Eval(interp,script);        
            }
            unsafe public string Result {
                get { 
                    IntPtr obj = TclAPI.Tcl_GetObjResult(interp);
                    if (obj == IntPtr.Zero) {
                        return "";
                    } else {
                        return Marshal.PtrToStringAnsi((IntPtr)TclAPI.Tcl_GetStringFromObj(obj,IntPtr.Zero));
                    }
                }
            }
        }
    }

    Using of it in C#

    TclInterpreter interp = new TclInterpreter(); string result; if (interp.evalScript("set a 3; {exp $a + 2}") != 0) { result = interp.Result; }


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    • 已标记为答案 zoromini 2016年10月20日 6:39
    • 取消答案标记 zoromini 2016年10月20日 7:41
    • 已标记为答案 zoromini 2016年10月21日 1:09
    2016年10月20日 2:47
  • 我把tcl84.dll复制过去了,但是在执行interp.evalScript的时候报错了,是不是因为没注册啊?
    2016年10月20日 5:19
  • 报错是这样的

    托管调试助手“PInvokeStackImbalance”在“C:\Users\Admin\Desktop\b\bin2\myApp.vshost.exe”中检测到问题。

    其他信息: 对 PInvoke 函数“myApp!myApp.TclAPI::Tcl_Eval”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。

    • 已标记为答案 zoromini 2016年10月21日 1:09
    • 取消答案标记 zoromini 2016年10月21日 1:09
    2016年10月20日 5:24
  • 根据错误,你应该检查

    unsafe public static extern char* Tcl_GetStringFromObj(IntPtr tclObj,IntPtr length);

    DllImport 这些函数的签名对不对。

    应该是签名你弄错了.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    • 已标记为答案 zoromini 2016年10月20日 6:38
    • 取消答案标记 zoromini 2016年10月20日 7:41
    • 已标记为答案 zoromini 2016年10月21日 1:09
    2016年10月20日 5:38
    版主
  • 好的,谢谢,我试试
    2016年10月20日 5:54
  • [DllImport("Dll.dll")]

    改为[DllImport("Dll.dll", CallingConvention=CallingConvention.Cdecl)]
    DllImport的CallingConvention的属性,默认值是CallingCovention.Stdcall,  此处更改成Cdecl(c/c++默认调用方式)就可以了。
    • 已标记为答案 zoromini 2016年10月21日 1:09
    2016年10月20日 6:38
  • 我执行tcl语句是可以了,但是我想加载自己写的package的时候直接程序就退出了,您了解吗

     interp.evalScript1("package require testMenu");

    2016年10月20日 7:42
  • 我执行tcl语句是可以了,但是我想加载自己写的package的时候直接程序就退出了,您了解吗

     interp.evalScript1("package require testMenu");

    2016年10月20日 7:42