首页 > 解决方案 > LNK2020:未解析的令牌(06000001)和 LNK4248:未解析的 typeref 令牌(0100001E)

问题描述

我已经用托管 C++ 编写了一个包装层,它与用 Native C++ 编写的第三方软件的 API 层接口。现在包装器可以正确编译和构建。构建顺序如下:(1)第三方API(Native C++并构建为库),(2)我在Managed C++中的warpper层(C++/CLR并构建为库),(3)编写的主要应用程序在托管 C++ 中使用我的包装器与第三方 API 进行通信。

现在,在我的包装层中有一些我想在主应用程序层(在上面的 3 中)使用的类,因此我想公开的方法,我已经编写了一个接口类,因此只公开我需要的第 3 层(即主应用层)。一个例子如下所示:

namespace RvBeehdClientApiWrapper
{
public ref class BeehdClientInitParamsWapper : public IBeehdClientInitParamsWapper
{
public:
    BeehdClientInitParamsWapper();

    ~BeehdClientInitParamsWapper();

    ///*virtual*/ bool get_VideoOutHwnd(unsigned long long^ newVal) { return true; };
    virtual bool put_VideoOutHwnd(unsigned long long newVal);

    ///*virtual*/ bool get_VideoLocalOutHwnd(unsigned long long^ newVal) { return true; };
    virtual bool put_VideoLocalOutHwnd(unsigned long long  newVal);

    ///*virtual*/ bool get_VideoOutPncHwnd(unsigned long long^ pVal) { return true; };
    virtual bool put_VideoOutPncHwnd(unsigned long long newVal);

    ///*virtual*/ bool get_ConfigFilePath(String^ pVal) { return true; };
    virtual bool put_ConfigFilePath(String^ newVal);

    ///*virtual*/ bool get_ProgramDataPath(String^ pVal) { return true; };
    virtual bool put_ProgramDataPath(String^ newVal);

    ///*virtual*/ bool get_LogFilesNumber(unsigned long^ pVal)  { return true; };
    virtual bool put_LogFilesNumber(unsigned long newVal);

    ///*virtual*/ bool get_LogFilesSize(unsigned long^ pVal)  { return true; };
    virtual bool put_LogFilesSize(unsigned long newVal);

    ///*virtual*/ bool get_LogsPath(String^ pVal) { return true; };
    virtual bool put_LogsPath(String^ newVal);

    ///*virtual*/ bool get_LicenseFilePath(String^ pVal) { return true; };
    virtual bool put_LicenseFilePath(String^ newVal);

    ///*virtual*/ bool get_IotFilePath(String^ pVal) { return true; };
    virtual bool put_IotFilePath(String^ newVal);

    virtual bool put_HistoryFilePath(String^ newVal);

    virtual bool put_IsAppLogEnabled(bool newVal);

    virtual bool put_IsLogContinuityOnStart(bool newVal);

    const CBeehdClientInitParamsImpl* get_InitializationParams() { return m_InitializationParams; }


private:
    CBeehdClientInitParamsImpl*          m_InitializationParams;

};
}

其接口类如下:

namespace RvBeehdClientApiWrapper
{
public interface class IBeehdClientInitParamsWapper
{
    bool put_VideoOutHwnd(unsigned long long newVal);
    bool put_VideoLocalOutHwnd(unsigned long long  newVal);
    bool put_VideoOutPncHwnd(unsigned long long newVal);
    //bool get_ConfigFilePath(String^ pVal);
    bool put_ConfigFilePath(String^ newVal);
    //bool get_ProgramDataPath(String^ pVal);
    bool put_ProgramDataPath(String^ newVal);
    //bool get_LogFilesNumber(unsigned long^ pVal);
    bool put_LogFilesNumber(unsigned long newVal);
    //bool get_LogFilesSize(unsigned long^ pVal);
    bool put_LogFilesSize(unsigned long newVal);
    //bool get_LogsPath(String^ pVal);
    bool put_LogsPath(String^ newVal);
    //bool get_LicenseFilePath(String^ pVal);
    bool put_LicenseFilePath(String^ newVal);
    //bool get_IotFilePath(String^ pVal);
    bool put_IotFilePath(String^ newVal);
    bool put_HistoryFilePath(String^ newVal);
    bool put_IsAppLogEnabled(bool newVal);
    bool put_IsLogContinuityOnStart(bool newVal);
};
}

主应用层通过 Factory 类使用 BeehdClientInitParamsWapper。工厂类的工作是创建 BeehdClientInitParamsWapper 类的单例实例并返回该实例,以便可以使用它来获取 IBeehdClientInitParamsWapper 类公开的方法。请参阅下面的 BeehdClientInitParamsWapper 工厂类的实现:

#pragma once
 #include "IApiWrapperClass.h"

 using namespace System;

namespace RvBeehdClientApiWrapper
{
ref class ApiWrapperClass;

public interface class IApiWrapperFactory
{
    IApiWrapperClass^ GetWrapperApiInstance();
};

public ref class ApiWrapperFactory : public IApiWrapperFactory
{
public:
    ApiWrapperFactory() {}
    ~ApiWrapperFactory() {}

    virtual IApiWrapperClass^ GetWrapperApiInstance();

private:

    static ApiWrapperClass^  m_theWrapperInstance;
};
}

工厂类的主体如下:

   #include "ApiWrapperFactory.h"
   #include "RvBeehdClientApiWrapper.h"


   RvBeehdClientApiWrapper::IApiWrapperClass^   RvBeehdClientApiWrapper::ApiWrapperFactory::GetWrapperApiInstance()
   {
     if (m_theWrapperInstance == nullptr)
     {
        m_theWrapperInstance = gcnew ApiWrapperClass();
     }
     return m_theWrapperInstance;
   }

Main应用层(上面3)使用的方法如下:

#include "BeehdClientInitParamsFactory.h"
#include "IBeehdClientInitParamsWapper.h"

bool RifMCDllMain::Start(...)
{
bool success = true;

try
{
    // Store the passed in RCA Config data reference.
    CConfigDetails ^ config = CConfigDetails::Instance;
    config->UseRcaConfig(rcaConfig);

    if (config->ReadConfigData())
    {
        // 1. Call Wrapper to populate the parameter object.
        RvBeehdClientApiWrapper::BeehdClientInitParamsFactory^ _ptrWrapperParamFactory = 
            gcnew RvBeehdClientApiWrapper::BeehdClientInitParamsFactory();
        RvBeehdClientApiWrapper::IBeehdClientInitParamsWapper^ _pwrapperparameters =
            _ptrWrapperParamFactory->get_WrapperInitParamsInstance();

        //Populate the parameter object.
        _pwrapperparameters->put_VideoOutHwnd(5049174);
        _pwrapperparameters->put_VideoLocalOutHwnd(992466);
        _pwrapperparameters->put_VideoOutPncHwnd(468162);
        ...
    }
    else
    {
        _log->Error("Read RIF config data failed");
        success = false;
    }

在实现所有这些之后,我按以下顺序编译解决方案:(i)第三方 API(本机 C++ 并作为库构建)->这将编译并创建一个库 (ii)我在托管 C++ 中的包装层(C++/ CLR 并作为库构建)->这将编译并创建我的包装器库 (iii) 使用我的包装器以托管 C++ 编写的主应用程序与第三方 API 进行通信->这会产生以下链接错误:

编译错误

编译错误

请告知,因为我真的被卡住了。提前谢谢了。

请看下面的编译错误:

1>------ Build started: Project: RifMC, Configuration: Debug Win32 ------
1>ConfigurationDetails.obj : /DEBUG:FASTLINK is not supported when managed code is present; restarting link with /DEBUG:FULL
1>ConfigurationDetails.obj : MSIL module encountered; incremental linking is disabled for MSIL; performing full link
1>RifMCDllMain.obj : warning LNK4248: unresolved typeref token (0100001E) for 'RvBeehdClientApiWrapper.ApiWrapperClass'; image may not run
1>RifMCDllMain.obj : warning LNK4248: unresolved typeref token (0100001F) for 'RvBeehdClientApiWrapper.BeehdClientInitParamsWapper'; image may not run
1>RifMCDllMain.obj : error LNK2020: unresolved token (06000069) RvBeehdClientApiWrapper.ApiWrapperFactory::GetWrapperApiInstance
1>RifMCDllMain.obj : error LNK2020: unresolved token (06000070) RvBeehdClientApiWrapper.BeehdClientInitParamsFactory::get_WrapperInitParamsInstance
1>C:\Git\DSxMissionCriticals\DSxSuper\MissionCritical\RifMC\Debug\RifMC.dll : fatal error LNK1120: 2 unresolved externals
1>Done building project "RifMC.vcxproj" -- FAILED.

========== 构建:0 成功,1 失败,0 最新,0 跳过 ==========

==================================================== ========================

namespace RvBeehdClientApiWrapper
{
ref class BeehdClientInitParamsWapper;

public interface class IBeehdClientInitParamsWapperFactory
{
    RvBeehdClientApiWrapper::IBeehdClientInitParamsWapper^ get_WrapperInitParamsInstance();
};

public ref class BeehdClientInitParamsFactory : public IBeehdClientInitParamsWapperFactory
{
public:
    BeehdClientInitParamsFactory() {}

    ~BeehdClientInitParamsFactory() {}

    virtual RvBeehdClientApiWrapper::IBeehdClientInitParamsWapper^ get_WrapperInitParamsInstance();

private:
    static BeehdClientInitParamsWapper^  m_theWrapperInitParamInstance;
};
}

本体如下图:

RvBeehdClientApiWrapper::IBeehdClientInitParamsWapper^ RvBeehdClientApiWrapper::BeehdClientInitParamsFactory::get_WrapperInitParamsInstance()
{
   if (m_theWrapperInitParamInstance == nullptr)
   {
       m_theWrapperInitParamInstance = gcnew  RvBeehdClientApiWrapper::BeehdClientInitParamsWapper();
   }
   return m_theWrapperInitParamInstance;
}

标签: c++-cli

解决方案


推荐阅读