Re: [GD-Windows] LNK1179: duplicate COMDAT (templates, vc2003)
Brought to you by:
vexxed72
From: Jon W. <hp...@mi...> - 2007-03-23 00:08:06
|
And the ACTUAL error, for those of who you need such things, is: media fatal error LNK1179: invalid or corrupt file: duplicate COMDAT '?Access@?$FieldArrayAccessor@USasCamera@impl_DX9@@M$GIA@A@A@@impl_DX9@@QAEPBMABUSasCamera@2@@Z' Cheers, / h+ Jon Watte wrote: > We're using VC 2003 (can't upgrade to 2005 just yet, although it's on > the long-term map). > > When building a certain file, which uses some moderately simple > templates, I get a linker error about duplicate COMDAT sections for a > specific template instantiation. It seems as if the function in question > is being instantiated twice in the same obj file by the compiler. > > Googling for this turns up a bunch of errors in VC6, which have nothing > to do with this problem, and a few people who had problems with some bg > in the incremental linker. I've turned off incremental linking for this > library (I'm building a DLL), and the error still happens. > > > I'm looking for the following things: > > 1) A fix for a known problem. > 2) Suggestions for how to work around this problem. > 3) A drinking buddy who has the same problem and can relate to the sorrow. > > > The code looks somewhat like: > > namespace impl_DX9 { > > template<typename Container, typename Type, Type (Container::*Field)[]> > class FieldArrayAccessor { > public: > typedef Container ContainerType; > typedef Type FieldType; > Type const *Access(Container const &c) { return c.*Field; } > }; > > // Match SasCamera > struct SasCamera { > Mat4Float worldtoview; // will always be the identity transform > Mat4Float projection; > float nearfarclipping[2]; > FastTriple position; // because the camera is always the > center of the world view, it's always 0,0,0 > }; > > > I have tried making the Access() functions be inline static, and regular > static as well (in fact, they started life out being inline static); I > still get this error. > > The three uses of the template in the file look like this: > > > return new WholeArraySetter<FieldArrayAccessor< > SasCamera, float, reinterpret_cast<float > (SasCamera::*)[]>(&SasCamera::nearfarclipping)> > >(pb, cam, 2); > > setter_ = new ArrayItemSetter<FieldArrayAccessor< > SasCamera, float, reinterpret_cast<float > (SasCamera::*)[]>(&SasCamera::nearfarclipping)> > > (this, core_->camera_, l); > > setter_ = new WholeArraySetter<FieldArrayAccessor< > SasSkeleton, pit::Mat4Float, reinterpret_cast<pit::Mat4Float > (SasSkeleton::*)[]>( > &SasSkeleton::meshtojointtoworld)> >(this, core_->skeleton_, > &core_->skeleton_.get().numjoints); > > > The templates that invoke the actual instance (Access function) look > like (look at the Update() functions): > > template<typename Accessor> > class WholeArraySetter : public IValueSetter { > public: > // When the count is fixed, stuff it in a member, and point the > pointer at that. > WholeArraySetter(ParameterBinder *bind, DirtyState<typename > Accessor::ContainerType> const &ds, int cnt) > : bind_(bind), ds_(ds), cnt_(cnt) { cntptr_ = &cnt_; } > // When the count is variable, bind using a pointer. The 'cnt' is > not used. > WholeArraySetter(ParameterBinder *bind, DirtyState<typename > Accessor::ContainerType> const &ds, int const *cnt) > : bind_(bind), ds_(ds), cntptr_(cnt) { cnt_ = -1; } > virtual void Dispose() { delete this; } > > virtual HRESULT Update(ID3DXEffect *fx) { > if (!ds_.dirty()) { > return S_OK; > } > //later: handle type casting (float->int, etc). > return fx->SetValue(bind_->param_, Accessor().Access(ds_.get()), > sizeof(typename Accessor::FieldType) * *cntptr_); > } > > ParameterBinder *bind_; > DirtyState<typename Accessor::ContainerType> const &ds_; > int cnt_; > int const *cntptr_; > }; > > template<typename Accessor> > class ArrayItemSetter : public IValueSetter { > public: > // When the count is fixed, stuff it in a member, and point the > pointer at that. > ArrayItemSetter(ParameterBinder *bind, DirtyState<typename > Accessor::ContainerType> const &ds, int cnt) > : bind_(bind), ds_(ds), cnt_(cnt) {} > virtual void Dispose() { delete this; } > > virtual HRESULT Update(ID3DXEffect *fx) { > if (!ds_.dirty()) { > return S_OK; > } > //later: handle type casting (float->int, etc). > return fx->SetValue(bind_->param_, Accessor().Access(ds_.get()) + > cnt_, > sizeof(typename Accessor::FieldType)); > } > > ParameterBinder *bind_; > DirtyState<typename Accessor::ContainerType> const &ds_; > int cnt_; > }; > > > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys-and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Gamedevlists-windows mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=555 > > > |