Note that there are some explanatory texts on larger screens.

plurals
  1. POError when using dllimport in a DLL client
    primarykey
    data
    text
    <p>Howdi folks, I'm currently creating a DLL and the client which goes with it using the stock procedure mentioned at a lot of places on the internet. Basically, create a DLL project which actually defines a PROJECT_EXPORTS in the Project.h file. Something like this:</p> <pre><code>// Assume the name of the project is SanProj and the header file is SanProj.h #ifdef SANPROJ_EXPORTS #define SANPROJ_API __declspec(dllexport) #else #define SANPROJ_API __declspec(dllimport) #endif </code></pre> <p>Now the normal way of using this header is to include this in all the headers of your API classes and using SANPROJ_EXPORTS for "exporting" declarations when in the DLL and "importing" declarations when used as a client. For e.g. let's say we have a header file with a currency class:</p> <pre><code>// currency.hpp #include "SanProj.h" #include &lt;ostream&gt; #include &lt;string&gt; namespace SanProj { class SANPROJ_API Currency { public: Currency(); const std::string&amp; name(); const std::string&amp; code(); bool empty() const; protected: std::string name_; std::string code_; }; SANPROJ_API bool operator==(const Currency&amp;, const Currency&amp;); SANPROJ_API bool operator!=(const Currency&amp;, const Currency&amp;); SANPROJ_API std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, Currency&amp; c); } </code></pre> <p>And another header file with specific currencies:</p> <pre><code>// allccy.hpp namespace SanProj { class SANPROJ_API USDCurrency : public Currency { public: USDCurrency() { name_ = "American Dollar"; code_ = "USD"; } }; class SANPROJ_API CADCurrency : public Currency { public: CADCurrency() { name_ = "Canadian Dollar"; code_ = "CAD"; } }; } </code></pre> <p>The above classes form the contract of the DLL project. Now let's look at the client project files, which is a single class with <code>main</code> function:</p> <pre><code>#include "currency.hpp" #include "allccy.hpp" #include &lt;iostream&gt; using namespace SanProj; int main(int argc, char* argv[]) { USDCurrency uccy; std::cout &lt;&lt; uccy; } </code></pre> <p>Assuming all referencing/settings are already done in the Visual Studio project, I get the following error when trying to compile the client:</p> <pre><code>1&gt;testdll.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall SanProj::USDCurrency::~USDCurrency(void)" (__imp_??1USDCurrency@SanProj@@QAE@XZ) 1&gt;testdll.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall SanProj::USDCurrency::USDCurrency(void)" (__imp_??0USDCurrency@SanProj@@QAE@XZ) </code></pre> <p>Not surprisingly, this error goes away when I remove the <code>dllimport</code> part from the <code>SanProj.h</code> file and the executable is created.</p> <p>My question is, what's the point of the IDE generated <code>dllimport</code> if we can't compile clients against the header? Is there a way I can continue to use the header with both <code>dllimport</code> and <code>dllexports</code> and remove the linker errors? Also, why is it trying to resolve the symbol which has <code>dllimport</code> from the LIB file?</p> <p>TIA,<br> /sasuke</p> <p><strong>EDIT:</strong> Linker Command used by VisualStudio; as you can see, it has the LIB file.</p> <blockquote> <p>/OUT:"E:\vsprojects\SomeSln\Release\testdll.exe" /INCREMENTAL:NO /NOLOGO "E:\vsprojects\SomeSln\Release\SanProj.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /MANIFEST /ManifestFile:"Release\testdll.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"E:\vsprojects\SomeSln\Release\testdll.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /PGD:"E:\vsprojects\SomeSln\Release\testdll.pgd" /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE</p> </blockquote>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload