I’m experimenting with writing a wrapper class for SQLite to be exposed through a DLL using implicit linking, i.e. producing library and header files for consumers to compile and link against.
At the moment I’m exporting the wrapper class, but when I attempt to compile the project that consumes this wrapper class I’m getting linker errors about not being able to resolve the sqlite API calls, e.g. sqlite3_open. Both the wrapper class and the consumer are C++, but sqlite is C.
Why does the consumer need to know about functions that are not exposed to it (the whole point of the wrapper class)? Does this mean I need to modify the SQLite header to change its functions to have the appropriate _declspec(dllexport) decoration for all functions/the functions I’m wrapping? Are there alternatives to this change?
The linker errors:
libsqlite.lib(sqlitewrapper.oxl) : error LNK2019: unresolved external symbol _sq
lite3_close referenced in function "public: virtual __thiscall CSQLiteWrapper::~
CSQLiteWrapper(void)" (??1CSQLiteWrapper@@UAE@XZ)
libsqlite.lib(sqlitewrapper.oxl) : error LNK2019: unresolved external symbol _sq
lite3_open referenced in function "public: __thiscall CSQLiteWrapper::CSQLiteWra
pper(class ATL::CStringT<char,class ATL::StrTraitATL<char,class ATL::ChTraitsCRT
<char> > > const &)" (??0CSQLiteWrapper@@QAE@ABV?$CStringT@DV?$StrTraitATL@DV?$C
hTraitsCRT@D@ATL@@@ATL@@@ATL@@@Z)
libsqlite.lib(sqlitewrapper.oxl) : error LNK2019: unresolved external symbol _sq
lite3_free referenced in function "public: virtual void __thiscall CSQLiteWrappe
r::Exec(class ATL::CStringT<char,class ATL::StrTraitATL<char,class ATL::ChTraits
CRT<char> > > const &,int (__cdecl*)(void *,int,char * *,char * *))" (?Exec@CSQL
iteWrapper@@UAEXABV?$CStringT@DV?$StrTraitATL@DV?$ChTraitsCRT@D@ATL@@@ATL@@@ATL@
@P6AHPAXHPAPAD2@Z@Z)
libsqlite.lib(sqlitewrapper.oxl) : error LNK2019: unresolved external symbol _sq
lite3_exec referenced in function "public: virtual void __thiscall CSQLiteWrappe
r::Exec(class ATL::CStringT<char,class ATL::StrTraitATL<char,class ATL::ChTraits
CRT<char> > > const &,int (__cdecl*)(void *,int,char * *,char * *))" (?Exec@CSQL
iteWrapper@@UAEXABV?$CStringT@DV?$StrTraitATL@DV?$ChTraitsCRT@D@ATL@@@ATL@@@ATL@
@P6AHPAXHPAPAD2@Z@Z)
The root cause of my issue was that I was using the “lib” command to generate the library I was then linking against. As Ixop mentions, in that case I would need to make sure SQLite is getting added to my library even though it wasn’t directly exposed in the DLL.
However with implicit linking, what I should have been doing was using the IMPLIB linker directive to generate the library instead. Making this change to how I was building it fixed the issue.