Connecting Tech Pros Worldwide Help | Site Map
 
 
LinkBack Thread Tools Search this Thread
  #1  
Old September 19th, 2007, 11:15 PM
Michael Reichenbach
Guest
 
Posts: n/a
Default How to build a loadable tcl dll with visual studio (microsoft C compiler)?[crosspost in comp.lang.tcl and comp.lang.c++]

Example one from http://www.tcl.tk/man/tcl8.4/TclCmd/load.htm:

#include <tcl.h>
#include <stdio.h>
static int fooCmd(ClientData clientData,
Tcl_Interp *interp, int objc, char * CONST objv[]) {
printf("called with %d arguments\n", objc);
return TCL_OK;
}
int Foo_Init(Tcl_Interp *interp) {
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
return TCL_ERROR;
}
printf("creating foo command");
Tcl_CreateObjCommand(interp, "foo", fooCmd, NULL, NULL);
return TCL_OK;
}

My compile.bat (using the current MinGW gcc port):

set djgpp=c:\MinGW\djgpp.env
set path=%path%;c:\MinGW\bin
gcc -I C:\Tcl\include -s -shared -o a.dll a.cpp C:\Tcl\bin\tcl84.dll
pause

First example doesn`t compile. There is an error.

gcc -I C:\Tcl\include -s -shared -o
a.dll a.cpp C:\Tcl\bin\tcl84.dll
a.cpp: In function `int Foo_Init(Tcl_Interp*)':
a.cpp:13: error: invalid conversion from `int (*)(void*, Tcl_Interp*,
int, char*
const*)' to `int (*)(void*, Tcl_Interp*, int, Tcl_Obj* const*)'
a.cpp:13: error: initializing argument 3 of `Tcl_Command_*
Tcl_CreateObjComman
d(Tcl_Interp*, const char*, int (*)(void*, Tcl_Interp*, int, Tcl_Obj*
const*), v
oid*, void (*)(void*))'

Example two:

#include <windows.h>
#include <tcl.h>

#ifndef DECLSPEC_EXPORT
#define DECLSPEC_EXPORT __declspec(dllexport)
#endif // DECLSPEC_EXPORT

BOOL APIENTRY
DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
return TRUE;
}

EXTERN_C int DECLSPEC_EXPORT
Tcldemo_Init(Tcl_Interp* interp)
{
#ifdef USE_TCL_STUBS
Tcl_InitStubs(interp, "8.3", 0);
#endif
Tcl_Obj *version = Tcl_SetVar2Ex(interp, "tcldemo_version", NULL,
Tcl_NewDoubleObj(0.1), TCL_LEAVE_ERR_MSG);
if (version == NULL)
return TCL_ERROR;
int r = Tcl_PkgProvide(interp, "Tcldemo", Tcl_GetString(version));

// Call Tcl_CreateObjCommand etc.

return r;
}

EXTERN_C int DECLSPEC_EXPORT
Tcldemo_SafeInit(Tcl_Interp* interp)
{
// We don't need to be specially safe so...
return Tcldemo_Init(interp);
}

This compiled with same compile.bat without any errors or warnings.

I wanted to compile the second example also with visual studio
(microsoft C compiler) and I did add the c:\tcl\include and the
c:\tcl\lib paths. But it doesn`t work, there is an errormessage:

Error 1 error C2664: 'Tcl_CreateObjCommand' : cannot convert parameter 3
from 'int (__cdecl *)(ClientData,Tcl_Interp *,int,char *const [])' to
'Tcl_ObjCmdProc (__cdecl *)'

How can I fix it?

You also don`t need to answer this specific question. Any other example
code which will compile in visual studio and which can be used later as
a loadable tcl module would be much appreciated.
  #2  
Old September 20th, 2007, 01:55 AM
Don Porter
Guest
 
Posts: n/a
Default Re: How to build a loadable tcl dll with visual studio (microsoftC compiler)? [crosspost in comp.lang.tcl and comp.lang.c++]

Michael Reichenbach wrote:
Quote:
static int fooCmd(ClientData clientData,
Tcl_Interp *interp, int objc, char * CONST objv[]) {
With that prototype, your fooCmd routine is a
Tcl_CmdProc. It's a command procedure that takes
string arguments...
Quote:
Tcl_CreateObjCommand(interp, "foo", fooCmd, NULL, NULL);
....but you are passing fooCmd to
Tcl_CreateObjCommand() and Tcl_CreateObjCommand
expects a Tcl_ObjCmdProc, and not a Tcl_CmdProc.
The compiler is telling you this error.

Either convert your fooCmd routine to be a
Tcl_ObjCmdProc -- a command procedure that
takes (Tcl_Obj *) arguments -- or call
Tcl_CreateCommand() instead of
Tcl_CreateObjCommand().

DGP
  #3  
Old September 20th, 2007, 09:45 PM
Michael Reichenbach
Guest
 
Posts: n/a
Default Re: How to build a loadable tcl dll with visual studio (microsoftC compiler)? [crosspost in comp.lang.tcl and comp.lang.c++]

I wouldn`t say that I have understood everything. But with some magic,
putting some hints together it`s working now. Was really hard for me as
C++ beginner to get this working, because there was nowhere a working
sample on the web. I have written some step by step instructions, if
someone is interested in solving that problem, see here.

1. File -new project -name: Foo -win32 console application -dll

2. Tools -Options -VC++ Directorys -Include Files -added
C:\Tcl\include

3. C++ -precompiled headers -Not Using Precompiled Headers

4. Library files -C:\Tcl\lib

5. Project settings -Configuration Properties -Linker -Input ->
Additional Dependencies -added c:\tcl\lib\tclstub84.lib

6. use this source (my mistake was to use the #define after #include)
(without the extern "C" it`s also not working, you will get error
message while % load Foo.dll, it says can`t find Foo_Init procedure)

#define USE_TCL_STUBS 1

#include <tcl.h>
#include <stdio.h>

extern "C"
{
__declspec(dllexport) int Foo_Init(Tcl_Interp* interp);
}

static int fooCmd(ClientData clientData, Tcl_Interp *interp, int objc,
Tcl_Obj * CONST objv[]) {
printf("called with %d arguments\n", objc);
return TCL_OK;
}

int Foo_Init(Tcl_Interp *interp) {
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
return TCL_ERROR;
}
printf("creating foo command");
Tcl_CreateObjCommand(interp, "foo", fooCmd, NULL, NULL);
return TCL_OK;
}

7. Debug -change to Release

8. Build -Build solution -compiles without any errors -in project
folder under release is File Foo.dll with ~6 kb
 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 205,338 network members.