gpt4 book ai didi

c# - VC++ 在解决方案中从非/clr 项目的函数调用/clr 项目的函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:04:48 30 4
gpt4 key购买 nike

我提到了 this somewhat similar question在问这个之前,但无法解决我的问题

我正在查看一个包含许多解决方案的旧应用程序。问题发生在其中一个解决方案中(比如 S)。这是情况:

  • S 中的一个项目(比如 P1)具有所有 C/C++ 文件,需要调用 C# 函数
  • 因为 P1 也包含 .c 文件,我不能使用 /clr 选项那个
  • 如果我将 P1 中的 .c 文件编译为 .cpp 文件,那么它会生成很多的错误,我不打算更改该遗留 .c 文件中的源
  • 所以我创建了另一个启用了/clr 的项目(比如P2),并为它创建了一个头文件函数声明和函数定义的 .cpp 文件;这在其下进行C#调用; P2 编译正常
  • 请注意,P1 是一个 .dll,而 P2 是作为静态库创建的;
  • P2 在 P1 的“框架和引用”中被提及

和一个警告:

warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library

现在有了所有这些,我在 P1 中得到了 3 个链接器错误:

error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in libcmtd.lib(typinfo.obj)

error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in libcmtd.lib(typinfo.obj)

error LNK1169: one or more multiply defined symbols found

此错误可在包括本网站在内的许多在线论坛上找到。但不知何故,在尝试了这些选项后我无法修复它(我是 .NET 框架的新手)。
重要的一点是,即使我从 P2 中删除 C# 代码,也会出现相同的错误。

修复它的正确方法是什么?

更新:

P2 仅包含 1 个带有函数声明的头文件和 1 个带有函数定义的源文件,这是对 C# 方法的 1 行调用;例如

void Class::foo () {  // A static function inside Class
std::string x = marshal_as<std::string>(C#_function);
// ...
}

P2 是新添加的,用/clr 编译(删除P2 使解决方案编译正常)。
我正在使用 /MD[d] 选项编译 P1 和 P2。而上面的错误是P1抛出的。

如果我将 P2 从静态库 (.lib) 转换为动态链接库 (.dll),那么上述错误就会消失。新的链接器错误来自 foo 本身的 undefined reference :

error LNK2019: unresolved external symbol "public: void __cdecl Class::foo()" referred in function { some function of P1 }

最佳答案

通过大量的反复试验以及在 StackOverflow 内外进行互联网搜索,我终于能够解决这个问题。至少链接器错误消失了,不知道还会弹出什么其他东西,但这是一个好兆头。
我将尝试在下面尽可能多地记录:

问题换句话说:

如何链接同一项目下的 2 个 dll,其中一个是 /clr和其他非clr

实际问题简述:

  • 一切正常,直到需求出现在其中一个解决方案,我必须调用 C# 模块。
  • 为了调用 C# 代码(或托管代码),项目必须是 /clr项目
  • 一个项目可以是/clr , 如果它包含所有 .cpp 代码而没有 .c 代码
  • 在我的例子中,解决方案中的主要项目包含 .c 文件;如果我尝试使用 .cpp 选项编译它,那么它会给出很多错误,并且由于遗留原因我无法更改该文件
  • 所以最好的选择是用 .h 和 .cpp 文件创建一个新项目其中将包含接口(interface)方法及其实现(分别调用 C# 或 C++/CLI)

到目前为止还不错,但是当新项目(P2)的函数定义没有与原始项目(P1)链接时,问题就来了。它给出了各种链接器错误。

解决方案:

VC++2010 的步骤适用于新手用户(比如我)。

配置 P1:

  • 右键单击解决方案 S 和 Add -> New Project -> Other
    languages -> VC++ -> CLR empty project
    并命名(比如P2);在项目的适当部分添加头文件和.cpp文件
  • 这会自动设置 Properties -> Configuration Properties ->
    C/C++ -> Code Generation -> Runtime Library to Multi threaded DLL:
    /MD[d]
    ;这是必不可少的
  • 对于原始项目P1,添加适当的includeProperties -> Configuration Properties -> C/C++ ->
    General -> Additional Include Directories
    下的路径;这样你就可以包括P1 源文件中任意位置的 P2 新头文件
  • 再次针对项目 P1,转到 Properties -> Common Properties ->
    Framework and Reference -> Add New Reference
    你应该能够在那里看到P2;只需添加它

配置 P2:

  • 第一步是可选的,因为即使没有那,但我正在记录; Properties -> Common Properties ->
    Framework and References -> Add New Reference -> <Select the C# or
    whatever external DLL you would want to call from P2>
  • 对于新项目 P2,将配置设置为 DLLProperties
    -> Configuration Properties -> General -> Project Defaults -> Configuration Type -> Dynamic Library (DLL)
  • 如果对项目 P2 有意义,您应该在同一页面中设置Output DirectoryIntermediate Directory也与 P1 同步(不完全相同)
  • 再次针对项目 P2 转到 Properties -> Configuration Properties ->
    Linker -> General -> Ignore Import Library -> No
    ;我这样做是因为P1也是这样
  • 现在是最重要的部分:无论你在里面添加了什么类P2的新头文件,我们需要提一下 __declspec(dllexport) (或 __declspec(dllimport) ,不确定但两者都有效);我从 this question 得到了这个重要信息和 this question

通过以上步骤构建成功!
可能会有遗漏的东西,因此我面临一些运行时问题。但是至少我能够在同一个解决方案下链接 2 个 DLL 项目,它们有和没有 /clr。 .

关于c# - VC++ 在解决方案中从非/clr 项目的函数调用/clr 项目的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18289805/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com