来自c#包的tcl需要错误

时间:2015-02-25 06:30:31

标签: c# package tcl require

我正在运行以下c#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

using System.Net;
using System.IO;

namespace TCLRunner
{
    class Program
    {
        private static TclInterpreter interp;
        static void Main(string[] args)
        {
            try
            {
                        interp = new TclInterpreter();
                        //interp.evalScript(@"cd ..");
                        interp.evalScript(@"set a ""this is a""");
                        interp.evalScript(@"puts ""Free text""");
                        interp.evalScript(@"puts $a");
                        interp.evalScript(@"package require Tcl");
                        printResults();
                        interp.evalScript(@"package require http");
                        printResults();
                        //
                        // 

                        // Shutdown and end connection



                }
                catch (Exception e)
                {
                    Console.WriteLine("SocketException: {0}", e);
                }
        }
        public static void printResults()
        {
            string result = interp.Result;
            Console.WriteLine("Received: {0}", result);
        }

    }

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));
                }
            }
        }
    }
}

我得到以下输出:

自由文字 这是一个 收到:8.4 收到:无法找到包http

它怎么找不到http包?

当我在tclsh上手动尝试相同的操作时,它没有任何问题。

谢谢!

1 个答案:

答案 0 :(得分:0)

您需要在调用Tcl_CreateInterp()之前初始化库。通过使用已知的二进制运行的名称调用Tcl_FindExecutable来初始化库,但可以相对安全地保留NULL;这是其他事件(名称不当)的功能,例如设置查找其库的位置。

C#中的正确声明是这样的(尽管在这种情况下MarshalAs属性是可选的):

[DllImport("tcl84.DLL")]
public static extern void Tcl_FindExecutable([MarshalAs(UnmanagedType.LPTStr)] string s);

你这样调用它,一次

TclAPI.Tcl_FindExecutable(null);

(作为TclAPI类中静态构造函数的一部分,这可能是最明智的。是的,它早期属于


如果这不起作用(我真的无法测试!),你必须set up some environment variables。关键一个是TCL_LIBRARY,它会覆盖默认位置Tcl查找其支持脚本(包括http包),您可能还需要设置TCLLIBPATH。 (请注意,TCL_LIBRARY主要是为了支持预安装测试,但有一段历史是由系统级别的 Python 设置其他不应该的系统。小心!

同样,这必须在Tcl_CreateInterp()电话之前完成。