I am not sure if this OT, but I will go ahead and post. If it has to be
posted elsewhere let me know.
-vijai.
------
I have a class declared as follows:
#pragma once
// a simple reference counter implementation
#ifndef __REF_COUNTER_H__
#define __REF_COUNTER_H__
#include <iosfwd>
#include "smlibdefs.h"
namespace SMLib
{
class SMLIBAPI_CLASS ReferenceCounter
{
unsigned long m_numrefs;
public:
ReferenceCounter();
ReferenceCounter(const ReferenceCounter&);
ReferenceCounter& operator = (const ReferenceCounter&);
virtual ~ReferenceCounter();
virtual void AcquireReference();
virtual void ReleaseReference();
virtual unsigned long CountReferences() const;
};
};
SMLIBAPI_FUNCTION std::ostream& operator << (std::ostream&, const
SMLib::ReferenceCounter&);
SMLIBAPI_FUNCTION std::wostream& operator << (std::wostream&, const
SMLib::ReferenceCounter&);
#endif
SMLIBAPI_FUNCTION is defined as __declspec(dllimport) or
__declspec(dllexport) depending on whether the class is being imported
or exported. (On Windows. On *nix I don't have to do anything to export
C++ classes I believe. All symbols are exported by default?)
I build a shared library and a static library. I test the class and
it's methods with the following separate test program.
#include <refcounter.h>
#include <windows.h>
#include <iostream>
#include <assert.h>
void Test_ReferenceCounter_Construction()
{
SMLib::ReferenceCounter ctr;
std::wcout<<L"Counter: "<<ctr<<std::endl;
}
void Test_ReferenceCounter_Initialization()
{
SMLib::ReferenceCounter ctr;
std::wcout<<L"Counter: "<<ctr<<std::endl;
assert(ctr.CountReferences() == 0);
}
void Test_ReferenceCounter_CopyConstruction()
{
SMLib::ReferenceCounter ctr;
std::wcout<<L"Counter 1: "<<ctr<<std::endl;
SMLib::ReferenceCounter ctr2 = ctr;
std::wcout<<L"Counter 2: "<<ctr2<<std::endl;
assert(ctr2.CountReferences() == 0);
}
void Test_ReferenceCounter_Assignment()
{
SMLib::ReferenceCounter ctr;
std::wcout<<L"Counter 1: "<<ctr<<std::endl;
ctr.AcquireReference();
ctr.AcquireReference();
SMLib::ReferenceCounter ctr2;
ctr2.AcquireReference();
std::wcout<<L"Counter 2: "<<ctr2<<std::endl;
ctr2 = ctr;
std::wcout<<L"Counter 2 (reassigned): "<<ctr2<<std::endl;
assert(ctr2.CountReferences() == ctr.CountReferences());
}
void Test_ReferenceCounter_ReferenceIncrement()
{
SMLib::ReferenceCounter ctr;
std::wcout<<L"Counter: "<<ctr<<std::endl;
ctr.AcquireReference();
assert(ctr.CountReferences() == 1);
}
void Test_ReferenceCounter_ReferenceDecrement()
{
SMLib::ReferenceCounter ctr;
std::wcout<<L"Counter: "<<ctr<<std::endl;
ctr.AcquireReference();
ctr.AcquireReference();
ctr.ReleaseReference();
assert(ctr.CountReferences() == 1);
}
int main()
{
LoadLibrary("smlib-1.0.0.0");
Test_ReferenceCounter_Construction();
Test_ReferenceCounter_Initialization();
Test_ReferenceCounter_Assignment();
Test_ReferenceCounter_ReferenceIncrement();
Test_ReferenceCounter_ReferenceDecrement();
return 0;
}
However, in the shared library:
I get an unresolved external error only for the overloaded left shift
operator. On the other hand for the static library I get unresolved
external symbols error for all the methods as well as the function. I
use the same makefile to compile both:
executableName = smlib
programName = smlib
version = 1.0.0.0
baseDir = .
incDir = $(baseDir)/
srcDir = $(baseDir)/
!if defined(DEBUG) || defined(_DEBUG)
buildSuffix = d
buildType = DEBUG
!else
buildSuffix =
buildType = RELEASE
!endif
ExtLibs = kernel32.lib \
msvcrt$(buildSuffix).lib \
libc$(buildSuffix).lib \
libcmt$(buildSuffix).lib
Includes = basedefs.h \
smlibdefs.h \
refcounter.h
OutPath = $(MAKEDIR)\$(buildType)
CCOpts = /c /Gd /MDd /EHa /D__SMLIB__BUILD /D$(buildType) /I$(incDir)
CC = cl.exe
LibOpts = /OUT:$(OutPath)\libsmlib-$(version).lib /NOLOGO
/SUBSYSTEM:NATIVE
LIB = lib.exe
LinkOpts = /$(buildType) /DLL /NOLOGO
/OUT:$(OutPath)\smlib-$(version).dll
/IMPLIB:$(OutPath)\smlib-$(version).lib
/PDB:$(OutPath)\smlib-$(version).pdb $(ExtLibs)
LINK = link.exe
refcounter: refcounter.cpp $(Includes)
$(CC) $(CCOpts) /Fo$(OutPath)/refcounter.obj refcounter.cpp
allObjs = $(OutPath)\refcounter.obj
lib: refcounter
$(LIB) $(LibOpts) $(allObjs)
dll: refcounter
$(LINK) $(LinkOpts) $(allObjs)
all: refcounter dll lib
clean:
del /Q $(OutPath)\*.obj
del /Q $(OutPath)\smlib-$(version).pdb
del /Q $(OutPath)\smlib-$(version).lib
del /Q $(OutPath)\smlib-$(version).exp
del /Q $(OutPath)\smlib-$(version).dll
del /Q $(OutPath)\smlib-$(version).ilk
Anyone have any ideas on what I am doing wrong?
thanks,
-vijai.