让CLR类库在CLR控制台应用程序中正常工作
我有一个包含三个项目的VS2026解决方案。核心是一个纯C++库,GUI是一个C++/CLI Windows窗体应用程序,提供.NET平台的能力,第三个是对核心的封装,向GUI提供输入。当我构建GUI时,我遇到了LNK1302错误:“仅支持链接安全的.netmodules;无法链接ijw/native .netmodule”。
为了用最小的方式模拟这个链接问题,我创建了一个包含两个项目的解决方案。第一个项目模拟包装器,作为一个“CLR Class Library”创建,以生成一个DLL,将与第二个项目链接。以下是在SimpleClassLibrary.h文件中生成后再修改以添加一个成员变量和一些访问方法的代码。
#pragma once
using namespace System;
namespace SimpleClassLibrary
{
public ref class Class1
{
String^ str {"Hello World!"};
public:
Class1 () {}
String^ GetString () {return str;}
void SetString (String^ s) {str = s;}
};
}
在SimpleClassLibrary.cpp中的全部代码只是:
#include "pch.h"
#include "SimpleClassLibrary.h"
第二个项目是一个“CLR控制台应用程序”,它的代码都在SimpleConsoleApplication.cpp文件中,内容是
#include "pch.h"
using namespace System;
#include "SimpleClassLibrary.h"
int main (array<System::String ^> ^args)
{
SimpleClassLibrary::Class1^ simple =
gcnew SimpleClassLibrary::Class1 ();
String^ str = simple->GetString ();
System::Console::WriteLine (str);
return 0;
}
相关的项目信息参数如下:
| 属性 | 值 |
|---|---|
| 输出目录 | $(SolutionDir)$(Platform)\$(Configuration)\ |
| 项目1 的配置类型 | 动态库 (.dll) |
| 项目2 的配置类型 | 应用程序 (.exe) |
| 平台工具集 | v145 for Microsoft C++ Build Tools |
| 公共语言运行时支持 | .NET Framework Runtime Support (/clr) |
| .NET目标框架版本 | v4.7.2 |
| 附加包含目录 | $(SolutionDir)include |
| 附加库目录 | $(SolutionDir)$(Platform)\$(Configuration)\ |
| 附加依赖项(Project 2) | SimpleClassLibrary.dll |
| 构建后事件(项目1) | copy *.h "$(SolutionDir)include" /Y |
但在尝试构建控制台应用程序时,我遇到了错误;
LNK1302: only support linking safe .netmodules; unable to link ijw/native .netmodule
我需要怎么做,才能让这两个项目一起工作?错误信息表明使用了“safe”编译,但改成“/clr:safe”会产生一大堆错误。
解决方案
感谢Hans Passant!
当你了解了其中的工作原理时,这东西其实很简单,
于是我把控制台应用程序项目属性中的“Additional Dependency”指向SimpleClassLibrary.dll的设置去掉,并在控制台项目中添加对SimpleClassLibrary的引用。把SimpleConsoleApplication.cpp的代码改成如下,结果,成功了。
#include "pch.h"
using namespace System;
using SimpleClassLibrary::Class1;
int main (array<System::String ^> ^args)
{
SimpleClassLibrary::Class1^ simple =
gcnew SimpleClassLibrary::Class1 ();
String^ str = simple->GetString ();
System::Console::WriteLine (str);
return 0;
}