visual-studio-2010 - Visual Studio, MSBuild : First build after a clean fails, 以下构建成功

标签 visual-studio-2010 visual-c++ build c++-cli linker-errors

我的构建显然有问题,但我无法弄清楚。我将其缩小到我的一个项目:clean 失败后的第一次构建,所有后续构建都成功。

我收到链接错误,表明某些符号已定义:

>------ Build started: Project: Problem, Configuration: Debug Win32 ------
> Blah blah blah...
23>     Creating library D:\SVN.DRA.WorkingCopy\Debug\Problem.lib and object D:\SVN.DRA.WorkingCopy\Debug\Problem.exp
23>ProblemDependency1.lib(PD1.obj) : error LNK2005: "public: unsigned short __thiscall PD2Class::getFoo(void)const " (?getFoo@PD2Class@@QBEGXZ) already defined in ProblemDependecy2.lib(ProblemDependency2.dll)
23>ProblemDependency1.lib(PD1.obj) : error LNK2005: "public: void __thiscall PD2Class2::`default constructor closure'(void)" (??_FPD2Class2@Image@DRA@@QAEXXZ) already defined in ProblemDependency2.lib(ProblemDependency2.dll)
23>D:\SVN.DRA.WorkingCopy\Debug\Problem.dll : fatal error LNK1169: one or more multiply defined symbols found
  • Problem 是一个 C++/CLI 项目,使用/clr 开关构建,它引用非托管 C++ 项目 ProblemDependency1(静态库)和 ProblemDependency2(DLL)。
  • ProblemDependency1 引用 ProblemDependency2。
  • getFoo() 被声明为内联并在类声明之外定义,在 .h 中
  • PD2Class2 没有显式定义的默认构造函数,但它有一个包含所有默认参数的构造函数,因此您可以说它包含默认构造函数作为特例
  • 定义这些的 .h 文件的第一行是 #pragma once。

有任何解决此问题的提示吗?如果需要,我可以发布更多信息

更新:感谢 Anders Abel 的建议,我解决了第一个错误,但我仍然无法解决第二个错误(关于默认构造函数的错误)

更新:如果我在 Visual Studio 之外使用 MSBuild 进行编译,它总是会失败,并出现同样的错误

编辑:这是一些代码。首先,PD2Class2 的一些声明。 PD2Class2的真名是CImage(懒得匿名了),CImage.h:

#pragma once
#pragma warning( disable: 4251 )    //TODO: Disable and solve

#include "ImageProperties.h"
#include "../CommonCppLibrary/CriticalSection.h"
#include <windows.h>
#include <stdexcept>
#include <string>

class CSharedMemory;
class EmptyImageException;
struct IShape;

struct SImageStatics {
    unsigned short low3Percentile;
    unsigned short high97Percentile;
    unsigned short medianPixelValue;
    unsigned short meanPixelValue;
    unsigned short minPixelValue;
    unsigned short maxPixelValue;
};

namespace DRA{
namespace Image{
class __declspec(dllexport) CImage {
    friend class CImageLock;

//Attributes
    int m_iPitch;
protected:
    mutable CImageProperties                    m_cProperties;
    CSharedMemory *                             m_pSharedMemmory;
    mutable DRA::CommonCpp::CCriticalSection    m_csData;
    static const float                          PIXEL_FREQUENCY_COVERAGE;
    static const float                          PIXEL_CUTOFF_PERCENTAGE;
    static const int                            MINIMUM_PIXEL_FREQUENCY;    //Pixels with a frequency lower than this are ignored
    static const int                            MINIMUM_WINDOW_WIDTH_FOR_16_BITS;

//Methods
    //Some private methods

public:

    CImage( DWORD dwWidth = 0, DWORD dwHeight = 0, ULONG uBytesPerPixel = 0,
            bool isSigned = false, EPhotometricInterpretation ePI = PI_UNKNOWN,
            UINT bitsStored = 0, float pw = -1.0f, float ph = -1.0f, BYTE * pData = NULL );
    CImage( const CImageProperties& cProperties, int iPitch = 0 );
    CImage( const CImage& rImage );
    virtual ~CImage();
    virtual CImage& operator=( const CImage& );
    bool operator==( const CImage& rImage );

//Alter State
    //More methods
//Query State
    //More methods
};
}
}

接下来,构造函数的定义,来自CImage.cpp:

CImage::CImage( DWORD dwWidth, DWORD dwHeight, ULONG uBytesPerPixel, bool isSigned,
                EPhotometricInterpretation ePI, UINT bitsStored, float pw, float ph,
                BYTE * pData ) :
        m_iPitch( dwWidth * uBytesPerPixel ),
        m_cProperties( dwWidth, dwHeight, uBytesPerPixel, bitsStored, ePI, isSigned, pw, ph ),
        m_pSharedMemmory( NULL ),
        m_csData(){
    m_pSharedMemmory = new CSharedMemory( pData ? pData : new BYTE[getSize()] );
}

最佳答案

getFoo() 是否标记为 __declspec(dllexport)?如果它是一个内联函数,它会从通过包含的 header 调用的任何位置实例化/使用。它不应该是 dll 导出的函数的一部分,也不应该有 dllexport 指令。

__declspec(dllexport) 可以通过扩展为 dllexportdllimport 的宏来处理,具体取决于它是 dll 还是代码使用已编译的 dll。如果函数声明中有任何宏,您可能需要深入研究它以查找是否有导出指令。

更新

我认为如果在构建dll时和使用dll时都使用头文件,那么在头文件中有__declspec(dllexport)是不正确的。而是使用宏系统:

#ifdef PROBLEMDEPENDENCY2
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif

class DLLEXPORT CImage
{
    //...
}

然后在构建 dll 时定义 PROBLEMDEPENDENCY2 预处理器符号,但在使用它时不定义。在头文件中硬编码 __declspec(dllexport) 的问题是编译器会尝试从 ProblemDependency2(正确)和 ProblemDependency1(不正确)导出类。

关于visual-studio-2010 - Visual Studio, MSBuild : First build after a clean fails, 以下构建成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6816990/

相关文章:

c# - 特定构建配置的不同配置字符串

c++ - 将输出帧保存为图像文件 CUDA 解码器

.net - 在 .NET Framework 中使用多个计时器

visual-c++ - const std::wstring 是如何编码的以及如何更改为 UTF-16

c++ - 哪些选项(如果有)在 Visual Studio 2015 中暗示/CLR

angular - ng serve 和 ng build [Angular 5] 的 cli 配置中的不同 Assets

asp.net - 是否支持在 Visual Studio 中验证(智能感知)内联 CSS3?

c++ - GCC 函数的 Visual C++ 版本

build - Phing和 Composer

objective-c - xCode 8.2.1 slow build objective-c with swift pod