2009-09-08 7 views
4

많은 것을 시도한 후 웹 옵션을 검색하여 컴파일하고 dll을로드하면 tcl에 대한 dll을 만들 수 없습니다. 어떻게하는지 설명해 주시겠습니까?tcl에서 dll loadable을 컴파일하는 방법

+0

http://wiki.tcl.tk/2419의 코드를 시도했지만 성공했지만 자신의 기능 (예 : HelloObjCmdProc)을 추가 할 수 없었습니다 – OliveOne

+0

지금까지 가지고있는 코드와 오류가 표시 될 수 있습니까? 코드가 컴파일 되나 TCL에로드되지 않습니까? 어떤 컴파일러와 DLL을 구축하는 데 사용하고 있습니까? – Jackson

답변

8

좋아, 여기에 간단한 예가 나와 있습니다. 이 코드는 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[]) ; 
extern "C" { 
    BASICTCLEXTN_API int Basictclextn_Init(Tcl_Interp *interp) ; 
} 

그리고 .cpp 파일

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

당신은 STDAFX.H에서 tcl.h #include를해야합니다.

이 예제는 Tcl 스텁 기능을 사용합니다. 자세한 내용은 Tcl_InitStubs 함수의 설명서를 참조하십시오. 스텁을 사용하는 경우 tclstub85.lib에만 링크해야합니다. 제대로 연결 코드를 얻으려면 다음을 수행해야합니다 -> C/C++ - 일반> -> 추가가 포함 디렉터리

  • 정의

    • (가) tcl.h이 구성 속성에 설치되어있는 디렉토리를 포함 추가 USE_TCL_STUBS 기호를 사용하면 일반적으로 속성 -> C/C++ -> 전 처리기 -> 전 처리기 정의에서이 작업을 수행합니다. 또한이 다음에 <DLLNAME>_EXPORTS (예 : BASICTCLEXTN_EXPORTS)을 정의해야하는 이유를 알 수 있습니다. 이유가 확실하지 않습니다.
    • 구성 특성 -> 링커 -> 일반 -> 추가 라이브러리 디렉토리에서 tclstub85.lib 파일이 추가 라이브러리 디렉토리 인 디렉토리 경로를 추가하십시오. > 링커 - - MSVCRT 다음 구성 속성에서 무시 라이브러리에 추가하여 MSVCRT를 제외에 대해 컴파일러가 경고를 뱉어 경우> 추가 의존성
    • -> 링커 - -> 입력
    • 는 구성 속성에 tclstub85.lib 추가> 입력 -> 특정 라이브러리 무시.

    이러한 .lib, .dll 및 .h 파일은 모두 Tcl 설치에서 쉽게 찾을 수 있습니다. 또한 관련 tclstub85.dll 및 tcl85.dll을 런타임에 찾을 수 있도록해야합니다. Tcl의 bin 디렉토리가 PATH에 있는지 확인하여 정렬해야합니다. 그래서 다음은 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 
    

    이 티클 exstention의 간단한 형태입니다, 당신은이 확장에 더 많은 commnds을 추가 Tcl_CreateObjCommand()에 추가 호출을 추가 할 수 있습니다. Tcl은 명령에 전달 된 명령 행 매개 변수 처리에 도움이되는 몇 가지 기능을 제공합니다. 예제 코드는 Tcl_WrongNumArgs()이지만, Tcl_GetIndexFromObj() 함수를 살펴 봐야합니다.

    브렌트 웰치 (Brent Welch)의 Tcl과 Tk에서 실용적인 프로그래밍의 사본을 얻을 것을 제안합니다. 여기에서 몇 가지 샘플 장을 읽을 수 있습니다. http://www.beedub.com/book/, Tcl에 대한 C 프로그래밍에 관한 장이 제 3 판에서 많이 도움이 될 것입니다.

  • +0

    BasicTclExtn.obj : 오류 LNK2019 : 해결되지 않은 외부 기호 "int __cdecl BasicExtnCmd (void *, struct Tcl_Interp *, int, struct Tcl_Obj * const * const)"함수에서 참조되는 __imp__Tcl_SetObjResult "BasicExtnCmd @@ YAHPAXPAUTcl_Interp @@ HQBQAUTcl_Obj @@@ Z) – OliveOne

    +0

    VS 2008 및 tcl8.5에서 include 및 lib의 모든 설정으로 컴파일하려고 시도한 후. – OliveOne

    +0

    미리 컴파일 된 헤더를 사용 했습니까? 빈 프로젝트를 사용하고 별도의 stdafx.h를 추가했습니다. – OliveOne

    관련 문제