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
>
>
>
|