c++-cli - 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;
}
解决方案
推荐阅读
- python - 如何使用sqlalchemy orm创建参数“缓存”设置为“无缓存”的oracle序列
- php - PHP for 循环,2 次相同的 id,随机
- python - Keras 模型在训练和验证中获得了很高的准确性,然后在混淆指标上搞砸了
- azure-devops - azure管道的yaml配置中的'At sign'是什么意思
- typescript - redux 动作创建者的类型
- r - R data.table 从多个 data.tables 的所有组合创建
- php - HTML表单动作无反应
- java - 找不到 mysql-bin.log 并出现验证错误
- android - 使用带有 AsyncTask 的 Jsoup 抓取 google 搜索首页失败?
- ios - 在 App Store Connect 中重置 iOS 应用版本编号