LINKER errors from static library created in 2010 C++ Express

95 views
Skip to first unread message

vbmrupp

unread,
Mar 5, 2012, 12:50:01 AM3/5/12
to xblite
When trying to link a static library in a simple exe. The linker gives
me the following errors. I compiled the lib in c++ express 2010 using
the compiler options
/Zi /nologo /W3 /WX- /O2 /Oy- /D "WIN32" /D "NDEBUG" /D
"_STATIC_CPPLIB" /Gm- /EHsc /MT /GS- .

What Am I doing wrong. The reason I am creating the Static lib, in the
first place is so, I won't have any dependencies when using it in
xblite.

Thanks


> Executing: C:\download\xblite\bin\xmake.exe -f "C:\download\xblite\demo\console\xblglobal\xblglobals.mak"
Microsoft (R) Program Maintenance Utility Version 1.50.4048
Copyright (c) Microsoft Corp 1988-93. All rights reserved.
link /entry:WinMain /NODEFAULTLIB /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /
RELEASE /NOLOGO /OPT:REF /ALIGN:4096 -out:xblglobals.exe
xblglobals.obj xblglobals.rbj xbl.lib xio.lib kernel32.lib msvcrt.lib
xblglobal.lib xblib.lib kernel32.lib advapi32.lib user32.lib gdi32.lib
comdlg32.lib winspool.lib
LINK : warning LNK4108: /ALIGN specified without /DRIVER; image may
not run
xblglobal.lib(btree.obj) : error LNK2019: unresolved external symbol
__lseeki64 referenced in function "void __cdecl freadx(unsigned char *
*,long,int,struct MSV *)" (?freadx@@YAXPAPAEJHPAUMSV@@@Z)
xblglobal.lib(btree.obj) : error LNK2019: unresolved external symbol
"int __cdecl _sopen(char const *,int,int,int)" (?_sopen@@YAHPBDHHH@Z)
referenced in function "int __cdecl btree(int,unsigned char *,unsigned
char *,struct MSV *)" (?btree@@YAHHPAE0PAUMSV@@@Z)
xblglobal.lib(btree.obj) : error LNK2019: unresolved external symbol
___iob_func referenced in function "void __cdecl sigint(int)" (?
sigint@@YAXH@Z)
xblglobal.lib(btree.obj) : error LNK2019: unresolved external symbol
"struct MSV * __cdecl AllocSV(void)" (?AllocSV@@YAPAUMSV@@XZ)
referenced in function "void __cdecl sigint(int)" (?sigint@@YAXH@Z)
xblglobals.exe : fatal error LNK1120: 4 unresolved externals
NMAKE : fatal error U1077: 'C:\windows\system32\cmd.exe' : return code
'0x460'
Stop.
> Execution finished.

D.

unread,
Mar 5, 2012, 3:30:08 AM3/5/12
to xbl...@googlegroups.com
You may be doing everything correctly. The problem may be due
to your static library as compiled by C++ express is not compatible
with the much older version of link.exe which is used with xblite.

Have you tried creating a DLL? Does it work with xblite?

D.

vbmrupp

unread,
Mar 5, 2012, 1:24:50 PM3/5/12
to xbl...@googlegroups.com
Thanks for responding.
 Actually, I was having issues with the curent version of linker that comes with xblite, so I took the initiative in copying the linker that comes with c++2010 express into the xblite\bin folder.
I tested it by compiling and linking some of the demos shipped with xblite and verified that it worked.
Notice the version of the linker in the output I posted
" Version 1.50.4048 "
 
 After posting this I recompiled the lib in c++express. I added the mscrt.lib under the LIB dependencies. The errors are gone. But Now when I compile the simple exe and run it, xblite will crash.
 When I get home, I will post the xblite code.
Thanks for your help

vbmrupp

unread,
Mar 19, 2012, 7:27:11 AM3/19/12
to xblite
Ok, I tried creating a DLL,but still have same issue.
The only way I was able to correct the linking errors was installing c+
+ express 2008.
When I googled the original issue, there was a a few people having
issues with 2010.

Now my question is different.

What is your suggestion for converting C to xblite syntax.
Ex:

[code]
enum cli_var_type {
cli_oid,
cli_bool,
cli_int1,
cli_int2,
cli_int4,
cli_int8,
cli_real4,
cli_real8,
cli_decimal,
cli_asciiz, /* zero terminated string */
cli_pasciiz, /* pointer to zero terminated string */
cli_cstring, /* string with counter */
cli_array_of_oid,
cli_array_of_bool,
cli_array_of_int1,
cli_array_of_int2,
cli_array_of_int4,
cli_array_of_int8,
cli_array_of_real4,
cli_array_of_real8,
cli_array_of_decimal,
cli_array_of_string, /* array of pointers to zero terminated
strings */
cli_any, /* use the same type for column as stored in the
database */
cli_datetime, /* time in seconds since 00:00:00 UTC, January 1,
1970. */
cli_autoincrement, /* column of int4 type automatically assigned
value during record insert */
cli_rectangle,
cli_unknown
};
typedef struct cli_field_descriptor {
enum cli_var_type type;
int flags;
char_t const* name;
char_t const* refTableName;
char_t const* inverseRefFieldName;
} cli_field_descriptor;

int cli_create_table(int session, char_t const* tableName, int
nColumns,
cli_field_descriptor* columns)

[code]

I created a .dec file with the following types
[code]
TYPE cli_field_descriptor
USHORT .type
XLONG .flags
ULONG .name
ULONG .refTableName
ULONG .inverseRefFieldName
END TYPE

EXTERNAL CFUNCTION SLONG cli_create_table(XLONG
session,tableName,ULONG nColumns,ANY)

[code]

The sample code that came from the author of the C code is using it
like this.

[code]
static cli_field_descriptor person_descriptor[] = {
{cli_asciiz, cli_hashed|cli_unique, _T("name")},
{cli_int4, cli_indexed, _T("salary")},
{cli_pasciiz, 0, _T("address")},
{cli_real8, 0, _T("rating")},
{cli_array_of_string, 0, _T("pets")},
{cli_array_of_oid, 0, _T("subordinates"), _T("person")}

rc = cli_create_table(session, _T("person"), sizeof(person_descriptor)/
sizeof(cli_field_descriptor),
person_descriptor);

[code]

I am able to correctly run a different C call in xblite client no
problem from this same Dll, but I am having issue with either the C
struct or the passing of the array of cli_field_descriptor struct;
because the application will crash.

Any guidance is appreciated.

Michael

Michael E

unread,
Mar 19, 2012, 8:43:08 AM3/19/12
to xbl...@googlegroups.com
Comments included below..

> Date: Mon, 19 Mar 2012 04:27:11 -0700
> Subject: [xblite] Re: LINKER errors from static library created in 2010 C++ Express
> From: vbm...@gmail.com
> To: xbl...@googlegroups.com
Enum's by default start with 0 then inc by 1.
So with XBlite we have:
$$CLI_OID = 0
$$CLI_BOOL = 1
$$CLI_INT1 = 2
etc..


> typedef struct cli_field_descriptor {
> enum cli_var_type type;
> int flags;
> char_t const* name;
> char_t const* refTableName;
> char_t const* inverseRefFieldName;
> } cli_field_descriptor;
 > int cli_create_table(int session, char_t const* tableName, int
> nColumns,
> cli_field_descriptor* columns)
>
> [code]
>
> I created a .dec file with the following types
> [code]
> TYPE cli_field_descriptor
> USHORT .type
> XLONG .flags
> ULONG .name
> ULONG .refTableName
> ULONG .inverseRefFieldName
> END TYPE

in C, sizeof(cli_field_descriptor) == 20 (x86 32bit), therefore ensure with XBLite that the TYPE size is also 20

.type is 32bits wide, so use either ULONG or XLONG. USHORT is 16
.flags i would use ULONG
for the 3 char pointers, i would use XLONG.
This gives:

TYPE cli_field_descriptor
ULONG .type
XLONG .flags
XLONG .name ' c pointer
XLONG .refTable ' c ptr
XLONG .InverseRefField 'c ptr
END TYPE
struct/type size is 20 bytes.

Can't help with the VS stuff as I use GCC.
> --
> You received this message because you are subscribed to the Google Groups "xblite" group.
> To post to this group, send email to xbl...@googlegroups.com.
> To unsubscribe from this group, send email to xblite+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/xblite?hl=en.
>

Michael Rupp

unread,
Mar 19, 2012, 2:48:45 PM3/19/12
to xbl...@googlegroups.com
Michael, thank you for pointing me in the right direction. I will give it a try later tonight.
How would I go about passing an array of struct cli_field_descriptor in the c function?
 Would it be something like this.
 
cli_field_descriptor  person_desc[6]
.....fill in the type fields of array
  person_desc[0].type = ....
  person_desc[0].name = &"column1"
 ..............
  rc = cli_create_table(session,tableName,6,@person_desc[])
 
Thanks again!
Michael

Michael E

unread,
Mar 19, 2012, 3:07:09 PM3/19/12
to xbl...@googlegroups.com

Mind attaching both relevant C header(s)  and the .dec file(s)?


Date: Mon, 19 Mar 2012 13:48:45 -0500
Subject: Re: [xblite] Re: LINKER errors from static library created in 2010 C++ Express

David Szafranski

unread,
Mar 19, 2012, 7:12:41 PM3/19/12
to xbl...@googlegroups.com
I would try using these definitions in the .dec file:

   $$cli_oid = 0
   $$cli_bool = 1
   $$cli_int1 = 2
   $$cli_int2 = 3
   $$cli_int4 = 4
   $$ cli_int8 = 5
   $$cli_real4 = 6
   $$cli_real8 = 7
   $$cli_decimal = 8
   $$cli_asciiz = 9         '/* zero terminated string */
   $$cli_pasciiz = 10     '/* pointer to zero terminated string */
   $$cli_cstring = 11      '/* string with counter */
   $$cli_array_of_oid = 12
   $$cli_array_of_boo = 13
   $$cli_array_of_int1 = 14
   $$cli_array_of_int2 = 15
   $$cli_array_of_int4 = 16
   $$cli_array_of_int8 = 17
   $$cli_array_of_real4 = 18
   $$cli_array_of_real8 = 19
   $$cli_array_of_decimal = 20
   $$cli_array_of_string = 21 '/* array of pointers to zero terminated strings */
   $$cli_any = 22                   '/* use the same type for column as stored in the database */
   $$cli_datetime = 23            ' /* time in seconds since 00:00:00 UTC, January 1, 1970. */
   $$cli_autoincrement = 24   '/* column of int4 type automatically assigned value during 
   $$cli_rectangle = 25
   $$cli_unknown = 26

TYPE CLI_FIELD_DESCRIPTOR
   USHORT  .type
   USHORT  .flags

   ULONG .name
   ULONG .refTableName
   ULONG .inverseRefFieldName
END TYPE

EXTERNAL CFUNCTION cli_create_table (session, tableName, nColumns, tableArray)

And then you need to create an array

DIM CLI_FIELD_DESCRIPTOR cfd[5]

cfd[0].type = $$cli_asciiz
cfd[0].flags = $$cli_hashed | $$cli_unique
cfd[0].name = &"name"

cfd[1].type = $$cli_int4
cfd[1].flags = $$cli_indexed
cfd[1].name = &"salary"

... continue to fill array and then create table

rc = cli_create_table (session, &"person", UBOUND(cdf[])+1, &cdf[])


Hope this works...

D.






Michael Rupp

unread,
Mar 19, 2012, 11:27:48 PM3/19/12
to xbl...@googlegroups.com
The one cli.h has the declarations in it.
I have included the dec file.

I did try both your's and David's options but the app still crashes.
Thanks again for everyone's help!


cli.h
gigabase.dec

Michael Rupp

unread,
Mar 21, 2012, 5:40:11 PM3/21/12
to xbl...@googlegroups.com
I was finally able to run the application. When trying to create the table, the app will finish without the table being created.
In Visualstudio you can debug the DLL with the xblite application by choosing Debug, VS will allow you to browse to the client exe (in this case the xblite app) and step through the dll code.

I noticed that only the first cli_field_descriptor is being passed to the DLL. It seems that the array is not being passed to the DLL properly. Is there something wrong with the passthrough reference in the xblite code.

Here is the code:
*******************************************************************************
'
' ####################
' #####  PROLOG  #####
' ####################
'
' A console program template
'
VERSION "0.0001"
CONSOLE
'
' IMPORT "xst" ' Standard library : required by most programs
' IMPORT "xsx" ' Extended standard library
' IMPORT "xio" ' Console input/ouput library

IMPORT "xst_s.lib"
' IMPORT "xsx_s.lib"
' IMPORT "xio_s.lib"

' IMPORT "gdi32" ' gdi32.dll
' IMPORT "user32"  ' user32.dll
' IMPORT "kernel32"  ' kernel32.dll
' IMPORT "shell32" ' shell32.dll
IMPORT "msvcrt"  ' msvcrt.dll
  IMPORT "gigabase"
'
DECLARE FUNCTION Entry ()

'
'
' ######################
' #####  Entry ()  #####
' ######################
'
FUNCTION Entry ()
 SLONG session,rc
 STRING databaseName,tablename
 STATIC cli_field_descriptor person_descriptor[6]
 person_descriptor[0].type= $$cli_asciiz
person_descriptor[0].flags = $$cli_hashed | $$cli_unique
person_descriptor[0].name = &"name"

person_descriptor[1].type = $$cli_int4
person_descriptor[1].flags = $$cli_indexed
person_descriptor[1].name = &"salary"
'PRINT "person_descriptor[1].name =";person_descriptor[1].name 
 
person_descriptor[2].type = $$cli_pasciiz
person_descriptor[2].flags = 0
person_descriptor[2].name = &"address"
'PRINT "person_descriptor[2].name =";person_descriptor[2].name 
 
person_descriptor[3].type = $$cli_real8
person_descriptor[3].flags = 0
person_descriptor[3].name = &"rating"
 
person_descriptor[4].type = $$cli_array_of_string
person_descriptor[4].flags = 0
person_descriptor[4].name = &"pets"
 
person_descriptor[5].type = $$cli_array_of_oid
person_descriptor[5].flags = 0
person_descriptor[5].name = &"subordinates"

 databaseName = "test.db"
 tablename = "person"
  session = cli_create(&databaseName, 0, 0, 0)
    IF session < 0 THEN
'fprintf(stderr, &"cli_open failed with code %d\n", session)
PRINT "Error"
END IF
rc = cli_create_table(session,&tablename,4, &person_descriptor[])
PRINT "Just returned from cli_create_table with code ";rc
IF rc <>$$cli_ok THEN
PRINT "cli_alter_index failed with code "; rc
END IF
 
  a$ = INLINE$ ("Press Enter to quit >")

END FUNCTION
END PROGRAM

Michael Rupp

unread,
Mar 27, 2012, 12:08:00 AM3/27/12
to xbl...@googlegroups.com
Does anyone have an idea why passing an array of TYPE is only passing the first index and not the whole array?
I have been pouring through help files.
 I even tried using the EXTERNAL Keyword, but still only the first index is passed.
 Would it help if I included the ASM file for parsing?

Thanks for your help
Michael

Ken

unread,
Mar 27, 2012, 10:40:42 AM3/27/12
to xblite
The address of an array and the address of its first element are
identical, so passing the first element is the same as passing the
whole array.

You might try using the array handle operator && instead of &:

rc = cli_create_table(session, &tablename, 4, &&person_descriptor[])

Ken

On Mar 26, 11:08 pm, Michael Rupp <vbmr...@gmail.com> wrote:
> Does anyone have an idea why passing an array of TYPE is only passing the
> first index and not the whole array?
> I have been pouring through help files.
>  I even tried using the EXTERNAL Keyword, but still only the first index is
> passed.
>  Would it help if I included the ASM file for parsing?...
>
> read more »
>
> Thanks for your help
> Michael
>
>
>
> On Wed, Mar 21, 2012 at 4:40 PM, Michael Rupp <vbmr...@gmail.com> wrote:
> > I was finally able to run the application. When trying to create the
> > table, the app will finish without the table being created.
> > In Visualstudio you can debug the DLL with the xblite application by
> > choosing Debug, VS will allow you to browse to the client exe (in this case
> > the xblite app) and step through the dll code.
>
> > I noticed that only the first cli_field_descriptor is being passed to the
> > DLL. It seems that the array is not being passed to the DLL properly. Is
> > there something wrong with the passthrough reference in the xblite code.
>
> > Here is the code:
>
> > ***************************************************************************­****
> > '
> > On Mon, Mar 19, 2012 at 10:27 PM, Michael Rupp <vbmr...@gmail.com> wrote:
>
> >> The one cli.h has the declarations in it.
> >> I have included the dec file.
>
> >> I did try both your's and David's options but the app still crashes.
> >> Thanks again for everyone's help!
>
> >> On Mon, Mar 19, 2012 at 2:07 PM, Michael E <map...@hotmail.com> wrote:
>
> >>> Mind attaching both relevant C header(s)  and the .dec file(s)?
>
> >>> ------------------------------
> >>> Date: Mon, 19 Mar 2012 13:48:45 -0500
> >>> Subject: Re: [xblite] Re: LINKER errors from static library created in
> >>> 2010 C++ Express
>
> >>> From: vbmr...@gmail.com
> >>> To: xbl...@googlegroups.com
>
> >>> Michael, thank you for pointing me in the right direction. I will give
> >>> it a try later tonight.
> >>> How would I go about passing an array of struct cli_field_descriptor in
> >>> the c function?
> >>>  Would it be something like this.
>
> >>> cli_field_descriptor  person_desc[6]
> >>> .....fill in the type fields of array
> >>>   person_desc[0].type = ....
> >>>   person_desc[0].name = &"column1"
> >>>  ..............
> >>>   rc = cli_create_table(session,tableName,6,@person_desc[])
>
> >>> Thanks again!
> >>> Michael
>
> >>> On Mon, Mar 19, 2012 at 7:43 AM, Michael E <map...@hotmail.com> wrote:
>
> >>>  Comments included below..
>
> >>>  > Date: Mon, 19 Mar 2012 04:27:11 -0700
> >>> > Subject: [xblite] Re: LINKER errors from static library created in
> >>> 2010 C++ Express
> >>> > From: vbmr...@gmail.com
> >>> > > > RELEASE /NOLOGO /OPT:REF /ALIGN:4096- Hide quoted text -
>
> - Show quoted text -

Michael Rupp

unread,
Mar 27, 2012, 8:55:37 PM3/27/12
to xbl...@googlegroups.com

Ken,Thanks for responding back.
I did try using the && exactly as you suggested but only the first element is sent across to the C function.
Just as a trial, I loaded the array with 6 elements and sent over the second element only; like so.

rc = cli_create_table(session, &tablename, 4, &person_descriptor[1]) 

 When I step through the DLL in VS,I see the second element only.
 Is this a bug in xblite?

Thanks
Michael

David Szafranski

unread,
Mar 28, 2012, 3:45:15 AM3/28/12
to xbl...@googlegroups.com
First you need to make sure that the defined structure for cli_field_descriptor is the correct
size.

Also, the use of the _T macro for strings indicates that you may need to be using
unicode strings. If unicode is expected, then you would need to create wide strings. If the
C code uses the  preprocessor command "_UNICODE", then all the strings need to be
in unicode (wide strings).

D.

Guy1954

unread,
Mar 28, 2012, 7:02:10 AM3/28/12
to xbl...@googlegroups.com
Hi D.,

I've used extensively the TYPE keyword in viXen and I'm have some guidelines for its use.

I only use the TYPE definition only when the application doesn't rely in any way on the size of the individual fields.

I believe we have here a case where size matters: PACKED should be used in replacement of TYPE.

- Either it is an external buffer;
the record layout must be exact byte for byte, and I'd use the PACKED statement instead:

' external buffer layout
PACKED CLI_FIELD_DESCRIPTOR
   USHORT  .type
   USHORT  .flags


   ULONG .name
   ULONG .refTableName
   ULONG .inverseRefFieldName
END PACKED

- Or it is an internal user data type;
it follows XBLite's rules, and I'd used XLONG (xblite default type) for all the numeric fields:

' internal user data type
TYPE CLI_FIELD_DESCRIPTOR
   XLONG  .type
   XLONG  .flags

   XLONG .name
   XLONG .refTableName
   XLONG .inverseRefFieldName
END TYPE

Bye Guy

David Szafranski

unread,
Mar 28, 2012, 1:39:51 PM3/28/12
to xbl...@googlegroups.com
I agree. Good advice!

--
You received this message because you are subscribed to the Google Groups "xblite" group.
To view this discussion on the web visit https://groups.google.com/d/msg/xblite/-/Pr6id5ZjuWkJ.

Michael Rupp

unread,
Mar 28, 2012, 11:37:32 PM3/28/12
to xbl...@googlegroups.com
Hey Guy,David.
I tried both examples given. Nothing seems to change. I am attaching a screen-print of the debug session when the cli_field_descriptor array is passed to the DLL.

Thanks
Michael
print_screen.jpg
Reply all
Reply to author
Forward
0 new messages