如何在tcl中编译dll可加载 [英] How to compile dll loadable in tcl

查看:416
本文介绍了如何在tcl中编译dll可加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试很多并搜索web选项来编译和加载dll后,我无法为tcl创建dll。你能解释一下如何做到这一点。

解决方案

好的,这里是一个简单的例子。该代码编译并适用于Tcl8.5和VS2008。首先我创建了一个名为BasicTclExtn的导出符号的WIN32 dll项目。

  // BasicTclExtn.h 
#ifdef BASICTCLEXTN_EXPORTS
#define BASICTCLEXTN_API __declspec(dllexport)
#else
#define BASICTCLEXTN_API __declspec(dllimport)
#endif

int BasicExtnCmd(ClientData data,Tcl_Interp * interp,int objc,Tcl_Obj * CONST objv []);
externC{
BASICTCLEXTN_API int Basictclextn_Init(Tcl_Interp * interp);
}

然后.cpp文件

  // BasicTclExtn.cpp:定义DLL应用程序的导出函数。 
#includestdafx.h
#includeBasicTclExtn.h

int
BasicExtnCmd(ClientData数据,
Tcl_Interp * interp,
$ objc
Tcl_Obj * CONST objv [])
{

//检查参数数
if(objc!= 3){
Tcl_WrongNumArgs(interp,1,objv,arg arg);
返回TCL_ERROR;
}

long v1,v2,result;

if(Tcl_GetLongFromObj(interp,objv [1],& v1)!= TCL_OK)
return TCL_ERROR;

if(Tcl_GetLongFromObj(interp,objv [2],& v2)!= TCL_OK)
return TCL_ERROR;

result = v1 + v2;

Tcl_SetObjResult(interp,Tcl_NewIntObj(result));
返回TCL_OK;
}

//注意_Init函数名称的外壳
BASICTCLEXTN_API int Basictclextn_Init(Tcl_Interp * interp)
{
//链接到存根库扩展为可移植的
if(Tcl_InitStubs(interp,8.1,0)== NULL){
return TCL_ERROR;
}

//声明此C代码提供的软件包和版本
if(Tcl_PkgProvide(interp,BasicTclExtn,1.0)!= TCL_OK){
返回TCL_ERROR;
}

//创建命令
Tcl_CreateObjCommand(interp,BasicExtnCmd,BasicExtnCmd,(ClientData)NULL,(Tcl_CmdDeleteProc *)NULL);

返回TCL_OK;
}

您需要在stdafx.h中#include tcl.h。 p>

此示例使用Tcl存根工具,有关更多信息,请参阅Tcl_InitStubs函数上的文档;当使用存根时,您只需链接到tclstub85.lib。要使代码正确链接,您需要执行以下操作:




  • 将安装tcl.h的include目录添加到配置属性 - > C / C ++ - >常规 - >其他包含目录

  • 定义 USE_TCL_STUBS 符号,我通常在Properties-> C / C ++ - >预处理器 - >预处理器定义。您可能还会发现,然后需要在此之后定义< DLLNAME> _EXPORTS BASICTCLEXTN_EXPORTS )我不知道为什么会发生这种情况。

  • 将配置属性 - >链接器 - >常规 - >其他库目录中的tclstub85.lib文件作为附加库目录的路径添加到

  • 将tclstub85.lib添加到配置属性 - >链接器 - >输入 - >附加依赖

  • 如果编译器发出关于MSVCRT的警告,则将MSVCRT添加到忽略库配置属性 - >链接器 - >输入 - >忽略特定库。



所有这些.lib,.dll和。在您的Tcl安装中应该很容易找到h文件。您还需要确保在运行时可以找到相关的tclstub85.dll和tcl85.dll,确保Tcl的bin目录在PATH上应该排序。因此,您应该可以从Tcl中执行以下操作:

  C:\Projects\BasicTclExtn\Debug> tclsh 
%加载BasicTclExtn.dll
%BasicExtnCmd 1 2
3
%BasicExtnCmd 1 2.p
预期整数,但已获得2.p
% BasicExtnCmd 1 2
3
%BasicExtnCmd 1
错误#args:应为BasicExtnCmd arg arg
%BasicExtnCmd 1 3
4
%exit

这是Tcl exstention的最简单形式,您可以向 Tcl_CreateObjCommand添加其他调用()添加更多commnds到这个扩展。 Tcl提供了一些帮助处理命令行参数的方法。使用 Tcl_WrongNumArgs()的示例代码,但您还应该查看 Tcl_GetIndexFromObj()函数。



我也建议您在Bcl Welch的Tcl和Tk中获得实用编程的副本。您可以在这里阅读一些示例章节 http://www.beedub.com/book/ ,章节对于第三版的Tcl的C编程将帮助您很多。


After trying many and searching web option to compile and load dll I could not able to create dll for tcl. Can you explain me how to do this.

解决方案

Ok, here is a simple example. This code compiles and works for Tcl8.5 and VS2008. To start with I created a WIN32 dll project called BasicTclExtn that exported symbols.

// BasicTclExtn.h
#ifdef BASICTCLEXTN_EXPORTS
#define BASICTCLEXTN_API __declspec(dllexport)
#else
#define BASICTCLEXTN_API __declspec(dllimport)
#endif

int BasicExtnCmd(ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) ;
extern "C" {
    BASICTCLEXTN_API int Basictclextn_Init(Tcl_Interp *interp) ;
}

And then the .cpp file

// BasicTclExtn.cpp : Defines the exported functions for the DLL application.
#include "stdafx.h"
#include "BasicTclExtn.h"

int
BasicExtnCmd(ClientData data,
             Tcl_Interp *interp,
             int objc,
             Tcl_Obj *CONST objv[])
{

    // Check the number of arguments
    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 1, objv, "arg arg");
        return TCL_ERROR;
    }

    long v1, v2, result ;

    if ( Tcl_GetLongFromObj(interp, objv[1], &v1) != TCL_OK)
        return TCL_ERROR ;

    if ( Tcl_GetLongFromObj(interp, objv[2], &v2)  != TCL_OK)
        return TCL_ERROR ;

    result = v1 + v2 ;

    Tcl_SetObjResult(interp, Tcl_NewIntObj(result)) ;
        return TCL_OK ;
}

    // Note the casing on the _Init function name
    BASICTCLEXTN_API int Basictclextn_Init(Tcl_Interp *interp)
    {
        // Link with the stubs library to make the extension as portable as possible
        if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
            return TCL_ERROR;
        }

        // Declare which package and version is provided by this C code
        if ( Tcl_PkgProvide(interp, "BasicTclExtn", "1.0") != TCL_OK ) {
            return TCL_ERROR ;
        }

        // Create a command
        Tcl_CreateObjCommand(interp, "BasicExtnCmd", BasicExtnCmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);

        return TCL_OK ;
    }

You need to #include tcl.h in the stdafx.h.

This example uses the Tcl stubs facility, see the documentation on the Tcl_InitStubs function for more information; when using stubs you need to link to only the tclstub85.lib. To get the code to link properly you need to do the following:

  • Add the include directory where tcl.h is installed to Configuration Properties -> C/C++ -> General -> Additional Include Directories
  • Define the USE_TCL_STUBS symbol, I normally do this in Properties-> C/C++ -> Preprocessor -> Preprocessor Definitions. You may also find that you then need to define the <DLLNAME>_EXPORTS (BASICTCLEXTN_EXPORTS in my example) after this, I'm not sure why this happens.
  • Add the path to the directory where the tclstub85.lib file is as an additional library directory in Configuration Properties -> Linker -> General -> Additional Library Directories.
  • Add tclstub85.lib to Configuration Properties -> Linker -> Input -> Additional Dependancies
  • If the compiler spits out a warning about MSVCRT then exclude MSVCRT by adding it to the ignored libraries in Configuration Properties -> Linker -> Input -> Ignore Specific Library.

All of these .lib, .dll and .h files should be easily found in your Tcl installation. You'll also need to ensure that the related tclstub85.dll and tcl85.dll can be found at run time, making sure the bin directory for Tcl is on the PATH should sort that out. So you should then be able to do the following from Tcl:

C:\Projects\BasicTclExtn\Debug>tclsh
% load BasicTclExtn.dll
% BasicExtnCmd 1 2
3
% BasicExtnCmd 1 2.p
expected integer but got "2.p"
% BasicExtnCmd 1 2
3
% BasicExtnCmd 1
wrong # args: should be "BasicExtnCmd arg arg"
% BasicExtnCmd 1 3
4
% exit

This is the simplest form of Tcl exstention, you can add additional calls to Tcl_CreateObjCommand() to add more commnds into this extension. Tcl provides some faciities to help with the processing of the command line paramters passed into the command. The example code used Tcl_WrongNumArgs() but you should also look at the Tcl_GetIndexFromObj() functions.

I would also suggest you get a copy of Practical Programming in Tcl and Tk by Brent Welch. You can read some sample chapter here http://www.beedub.com/book/, the chapter on C programming for Tcl from the 3rd edition will help you a lot.

这篇关于如何在tcl中编译dll可加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆