Deal of the Month: 50% Discount on Windows 7 (Limited Amazon.com offer) Main Page | Report this Page
Computers Forum Index  »  Computer Languages (TCL)  »  Compiling TCL C++ extension (.so) in cygwin environment
Page 1 of 2    Goto page 1, 2  Next

Compiling TCL C++ extension (.so) in cygwin environment

Author Message
Michael
Posted: Thu Feb 16, 2006 11:13 pm
Guest
Hi I'm trying to build my C++ extension to run in cygwin tclsh
so I can test stuff on my laptop. This is what I do to build the .so

g++ -c -shared -fPIC filemap.cpp cao.cpp -I.
g++ -shared -fPIC -o libcao.so cao.o filemap.o -ltcl84 -L/lib

This complies with no problems. However when I load in tclsh I get the
following error:

$ tclsh
% load ./libcao.so
couldn't load library "./libcao.so": invalid argument

Any ideas?

Michael
 
Michael
Posted: Thu Feb 16, 2006 11:43 pm
Guest
BTW, the same compiles and works on SunOS 5.9.
 
Ralf Fassel
Posted: Fri Feb 17, 2006 12:43 am
Guest
* "Michael" <chun.tse@evolving.com>
| g++ -c -shared -fPIC filemap.cpp cao.cpp -I.

Usually -shared only goes in the link stage, not in the compile stage.
Don't know if that hurts here...

| $ tclsh
| % load ./libcao.so
| couldn't load library "./libcao.so": invalid argument

Is this tclsh matching the tcl84 library used to link your .so?
Did you verify that libcao.so indeed contains the object files
(eg list via nm).

R'
 
Dave Bodenstab
Posted: Fri Feb 17, 2006 4:13 am
Guest
Michael wrote:
Quote:
Hi I'm trying to build my C++ extension to run in cygwin tclsh
so I can test stuff on my laptop. This is what I do to build the .so

g++ -c -shared -fPIC filemap.cpp cao.cpp -I.
g++ -shared -fPIC -o libcao.so cao.o filemap.o -ltcl84 -L/lib

This complies with no problems. However when I load in tclsh I get the
following error:

$ tclsh
% load ./libcao.so
couldn't load library "./libcao.so": invalid argument

Any ideas?

Cygwin (windoze) requires a .dll extension. Look in the Cygwin
docs; there's an example of how to build a .dll. I've been
compiling TclMagick on Cygwin using (paraphrased):

gcc -mno-cygwin -DUSE_TCL_STUBS -I$(TCL_PREFIX)/include -c file.c
gcc -mno-cygwin -shared -L$(TCL_PREFIX)/lib -o file.dll -ltclstub84

This creates the .dll. I am able to generate the pkgIndex.tcl and
use the package with active state's tcl.
 
Erik Leunissen
Posted: Fri Feb 17, 2006 4:15 am
Guest
Michael wrote:
Quote:

g++ -c -shared -fPIC filemap.cpp cao.cpp -I.
g++ -shared -fPIC -o libcao.so cao.o filemap.o -ltcl84 -L/lib

The "-L/lib" option will make the linker search in the /lib directory
for any libraries specified on the command line *after* "-L/lib".

Because there is nothing on the command line after "-L/lib", this option
has no effect. You probably did not intend that.

Erik Leunissen
--
leunissen@ nl | Merge the left part of these two lines into one,
e. hccnet. | respecting a character's position in a line.
 
Michael
Posted: Fri Feb 17, 2006 4:27 am
Guest
Quote:
Cygwin (windoze) requires a .dll extension

Actually single threaded apps built in cygwin environment run faster on
my laptop than on the target sun SPARC IV platform (built with CC). I
see no difference in compiling with -o name.so and -o name.dll

Quote:
The "-L/lib" option will make the linker search in the /lib directory
for any libraries specified on the command line *after* "-L/lib".

I put the -L option there because the linker wouldn't be able to find
the tcl lib.

Quote:
Is this tclsh matching the tcl84 library used to link your .so?
Did you verify that libcao.so indeed contains the object files

Yes, objects are there.

Any other ideas? I need to build with g++ as the extension is written
in C++
 
Ralf Fassel
Posted: Fri Feb 17, 2006 2:15 pm
Guest
* "Michael" <chun.tse@evolving.com>
| I need to build with g++ as the extension is written in C++

Wild guess... is your init() routine declared extern "C"? Tcl tries
to run the Cao_Init() function when loading the library, and this has
to be non-C++-name-mangled. But then, if this were the error I would
have expected something along the lines of `could not find init
routine'.

R'
 
Michael
Posted: Fri Feb 17, 2006 2:22 pm
Guest
Hi, yes. I can get the working on sun so the code should be fine.

I tried with (should make a difference because I'm not worried about
running outside cygwin)

dllwrap --driver-name g++ -o libcao.dll cao.o filemap.o -ltcl84 -lm
-lstdc++

but still get the same error which trying to load.

I guess I need to find out what the error meesage means.

tclsh
load % libcao.dll
couldn't load library "libcao.dll": invalid argument


#include <tcl.h>
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <time.h>
#include <filemap.h>

extern "C" {
int Cao_Init(Tcl_Interp *interp);
int setVar(
Tcl_Interp *interp, Tcl_Obj * CONST objv[],
std::vector<filemap::fieldinfo>::iterator itr,
std::vector<filemap::fieldinfo>::iterator end);
int Get_Rec( ClientData clientData, Tcl_Interp *interp, int objc,
Tcl_Obj * CONST objv[]);
int Cao_Cmd( ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj
* CONST objv[]);
int Get_Rec( ClientData clientData, Tcl_Interp *interp, int objc,
Tcl_Obj * CONST objv[]);

int Get_Dump ( ClientData clientData, Tcl_Interp *interp, int objc,
Tcl_Obj * CONST objv[]);
int Fin_Cmd( ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj
* CONST objv[]);
}

filemap * fm;

...... function declared

int
Cao_Init(Tcl_Interp *interp)
{

if (Tcl_InitStubs(interp, TCL_VERSION, 0) == 0L) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "cao::parse", Cao_Cmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "cao::dump", Get_Dump, NULL, NULL);
Tcl_CreateObjCommand(interp, "cao::get", Get_Rec, NULL, NULL);
Tcl_CreateObjCommand(interp, "cao::finished", Fin_Cmd, NULL, NULL);
Tcl_PkgProvide(interp, "Cao", "1.0");
return TCL_OK;
}
 
Ralf Fassel
Posted: Fri Feb 17, 2006 2:37 pm
Guest
* "Michael" <chun.tse@evolving.com>
| int
| Cao_Init(Tcl_Interp *interp)
| {

Make this the only function in the whole library and put some stderr
output right here to see if you arrive here at all. Leave out
everything, just do a return TCL_OK and see whether this works. Then
line by line add your functionality and see where it breaks.

R'
 
Christian Gollwitzer
Posted: Fri Feb 17, 2006 2:41 pm
Guest
Michael wrote:
Quote:
Hi I'm trying to build my C++ extension to run in cygwin tclsh
so I can test stuff on my laptop. This is what I do to build the .so

g++ -c -shared -fPIC filemap.cpp cao.cpp -I.
g++ -shared -fPIC -o libcao.so cao.o filemap.o -ltcl84 -L/lib

This complies with no problems. However when I load in tclsh I get the
following error:

$ tclsh
% load ./libcao.so
couldn't load library "./libcao.so": invalid argument

It works for me, C++ extension wrapped up with SWIG on Cygwin. Are you
sure your tclsh is really cygwin and not windows? I remember that the
supplied "wish" once was/yet is a "normal" windows application without
cygwin, which of course can't load cygwin .so You may try to either
compile your extension with "-mno-cygwin" (but note that this is porting
to windows and may change semantics of some libc functions), or try to
recompile Tcl from sources with "configure" from the unix directory.
In any case, the libtcl you link with must match your tclsh.

Christian
 
Sektor van Skijlen
Posted: Fri Feb 17, 2006 2:49 pm
Guest
Dnia 16 Feb 2006 10:13:58 -0800, Michael skrobie:
Quote:
Hi I'm trying to build my C++ extension to run in cygwin tclsh
so I can test stuff on my laptop. This is what I do to build the .so

g++ -c -shared -fPIC filemap.cpp cao.cpp -I.
g++ -shared -fPIC -o libcao.so cao.o filemap.o -ltcl84 -L/lib

This complies with no problems. However when I load in tclsh I get the
following error:

$ tclsh
% load ./libcao.so
couldn't load library "./libcao.so": invalid argument

Beware that Cygwin currently uses Windows (NOT Cygwin!) version of tclsh84.

I don't know, why. I succeeded to compile tclsh8.5 on my Cygwin in Cygwin
native version and I succeeded. Maybe the problem is with Tk, I didn't try it.

You have to compile your dynamic library as a Windows dll. This is loadable
from tclsh, but I didn't try, how it works.

After some small changes, it is possible to use dll's on a native Tclsh on
Cygwin, but I don't remember how I did it (it was some homecooked version
compiled with unix rules with manually compiled-in windows version for dynamic
libraries).


--
// _ ___ Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `| /^\ ,() <ethourhs(O)wp.pl>
// \_ |\ \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"I am allergic to Java because programming in Java reminds me casting spells"
 
Benjamin Riefenstahl
Posted: Fri Feb 17, 2006 6:28 pm
Guest
Hi Michael,

"Michael" writes:
Quote:
int
Cao_Init(Tcl_Interp *interp)

This should probably be

DLLEXPORT int
Cao_Init(Tcl_Interp *interp)

Windows compilers usually do not export each and every global symbol
of a DLL to outside callers.

benny
 
Michael
Posted: Sun Feb 19, 2006 11:19 am
Guest
Thanks of all your replies. I tried the suggests apart from recompiling
tclsh.

If the tclsh that comes with the latest cygwin is built for windows
then this is probably the problem. When I build my extension I don't
use the -mno-cygwin option. When I do I get lots of errors but the lib
is created. Do I need to include some other lib?

In file included from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/stl_algobase.h:67,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/char_traits.h:46,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/string:47,
from filemap.cpp:1:
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cstdlib:181: error:
`::strtold' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cstdlib:200: error:
`__gnu_cxx::strtold' has not been declared
In file included from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/postypes.h:46,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/iosfwd:50,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/stl_algobase.h:70,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/char_traits.h:46,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/string:47,
from filemap.cpp:1:
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:146: error:
`::fgetwc' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:147: error:
`::fgetws' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:148: error:
`::fputwc' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:149: error:
`::fputws' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:150: error:
`::fwide' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:151: error:
`::fwprintf' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:152: error:
`::fwscanf' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:153: error:
`::getwc' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:154: error:
`::getwchar' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:159: error:
`::putwc' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:160: error:
`::putwchar' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:161: error:
`::swprintf' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:162: error:
`::swscanf' has not been declared
...

/usr/include/tcl.h:391: error: `__int64' does not name a type
/usr/include/tcl.h:392: error: `__int64' does not name a type
/usr/include/tcl.h:640: error: `Tcl_WideInt' does not name a type
/usr/include/tcl.h:776: error: `Tcl_WideInt' does not name a type
/usr/include/tcl.h:1457: error: ISO C++ forbids declaration of
`Tcl_WideInt' with no type
/usr/include/tcl.h:1457: error: typedef `Tcl_WideInt' is initialized
(use __typeof__ instead)
/usr/include/tcl.h:1457: error: `Tcl_DriverWideSeekProc' was not
declared in this scope
/usr/include/tcl.h:1457: error: expected `,' or `;' before '(' token
/usr/include/tcl.h:1545: error: ISO C++ forbids declaration of
`Tcl_DriverWideSeekProc' with no type
/usr/include/tcl.h:1545: error: expected `;' before '*' token
In file included from /usr/include/tcl.h:2250,
from cao.cpp:1:
/usr/include/tclDecls.h:1565: error: expected constructor, destructor,
or type conversion before '*' token
/usr/include/tclDecls.h:1565: error: expected `,' or `;' before '*'
token
/usr/include/tclDecls.h:2119: error: ISO C++ forbids declaration of
`Tcl_DriverWideSeekProc' with no type
/usr/include/tclDecls.h:2119: error: expected `;' before '*' token
In file included from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/stl_algobase.h:67,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/char_traits.h:46,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/string:47,
from cao.cpp:2:
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cstdlib:181: error:
`::strtold' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cstdlib:200: error:
`__gnu_cxx::strtold' has not been declared
In file included from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/postypes.h:46,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/iosfwd:50,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/stl_algobase.h:70,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/char_traits.h:46,
from
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/string:47,
from cao.cpp:2:
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:146: error:
`::fgetwc' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:147: error:
`::fgetws' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:148: error:
`::fputwc' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:149: error:
`::fputws' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:150: error:
`::fwide' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:151: error:
`::fwprintf' has not been declared
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/cwchar:152: error:
`::fwscanf' has not been declared
...
 
Michael
Posted: Sun Feb 19, 2006 4:56 pm
Guest
 
Michael
Posted: Sun Feb 19, 2006 5:45 pm
Guest
OK, it didn;t quite work. The run the example and it works. I created a
command in the example file and it work. The all I did was include the
c++ header file for my new class, recomplied and created the dll and
got the same error as before.

couldn't load library "tcldemo.dll": invalid argument

Why does including a header file cause a problem with loading the
library.
 
 
Page 1 of 2    Goto page 1, 2  Next
All times are GMT
The time now is Sun Nov 08, 2009 12:53 am