• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1570
  • Last Modified:

Unresolved external symbol _sqlite3_version from static lib

Hi everybody,

I try to use Sqlite in my project. I downloaded the code from http://www.sqlite.org/sqlite-amalgamation-3070800.zip.

When I build my project everything compiles fine but I recieve this (with MS VS 2010):
------ Build started: Project: MyApp, Configuration: Release Win32 ------
...
BaseLib.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _sqlite3_version

Open in new window

The 'BaseLib' is a static  library.

Maybe it's a name-mangling problem because the 'sqlite3_version' is a global variable declared as extern "C", but I'm not sure - if so I even have no idea how to solve this.

Does anyone know how I can solve this or what else could be the reason?

Thanks in advance,

ZOPPO



0
Zoppo
Asked:
Zoppo
  • 3
  • 3
1 Solution
 
sarabandeCommented:
name mangling only happens with function names but not with variables.

are you sure it is extern "C" ?  i would assume it is extern solely. then the sqllite_version needs to get defined in one of your cpp files (only one).

Sara
0
 
ZoppoAuthor Commented:
Hi sarabande,

thanks for the reply.

My guess about name mangling comes from the fact (I didn't mentioned before) the linker error is about '_sqlite3_version' but the variable in the code is 'sqlite3_version'. Don't know why ... there's no '_sqlite3_version' anywhere in the code.

>> are you sure it is extern "C" ?

The header where 'sqlite3_version' is decalred (sqlite3.h) looks somehow like this:
#ifdef __cplusplus
extern "C" {
#endif
...
# define SQLITE_EXTERN extern
...
# define SQLITE_API
...
SQLITE_API SQLITE_EXTERN const char sqlite3_version[];
...
#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif

Open in new window

The implementation (sqlite3.c) is
SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;

Open in new window

The file 'sqlite3.c' file is compiled as a C file (compiler switch /TC), the files where I include/use the 'sqlite3.h' are compiled as C++ files (compiler switch /TP). So, in case 'sqlite3.c' is compiled 'sqlite3_version' is declared extern (because __cplusplus isn't defined), in case I include the file in my CPP file it's declared as extern "C" and extern. Could this be a problem when building/linking with a static library?

Unfortunateley compiling the 'sqlite.c' as C++ file fails with lot of errors.

Any ideas?

ZOPPO
0
 
sarabandeCommented:
the extern "C" only prevents from name mangling of function names. it has no further meaning. the leading _ in the symbol names is done for all symbols. so it has no special meaning.

what is left is that the char[3] variable is declared as extern what is the reason that the linker looks for a definition of the (global) variable. here static libraries have a problem cause they don't have any main where the can define variables. the only other way to populate a global variable from a static library i know is to provide a static function.

so, in my opinion the solution is simple. in your main application c or cpp file define the variable as

const char sqlite3_version[] = "...";

where the ... should be a valid sqllite3 version string. i hope you know the version and notation of that string.

when doing so the linker should not longer complain.

note, libraries often provide some macro for the definition which you could use. it is like specifiying a GUID for COM in windows.

Sara

p.s.

the sqllite.c may contain the version string, perhaps via macro. if so, simply add the sqllite.c to your project and it should compile (as c) and link.

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
ZoppoAuthor Commented:
Hi sarabande,

thanks a lot for your help - I wanted to avoid the need to do something specific in the application since I plan to use that static lib in multiple applications/DLLs. But with the input you gave me I found a way to force the linker to export the symbol from the lib - to do so I added this to a CPP file within the static lib:
#pragma comment(linker, "/export:_sqlite3_version,DATA")

Open in new window

With this all is built fine and accessing 'sqlite3_version' from my main app returns the correct data.

Thanks again,

Have a nice day,

best regards,

ZOPPO
0
 
sarabandeCommented:
i thank you. i think it is a clever idea to let the library export the symbol.

did you try to print out the contents of the variable? is it empty?

have a nice day, too.

Sara

0
 
ZoppoAuthor Commented:
Yes, I printed it out and it is the correct and expected value "3.7.8" which is assigned in 'sqlite3.c'. Absoluteley perfect :o) ... thanks agian ...


0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now