27

我刚刚开始了一个 C# 项目,并且想要导入一个 C++ .lib 及其对应的头 (.h) 文件。

我读过各种帖子都提到.dll,而不是.lib,这让我很困惑。

下图显示了我所指的 .lib 和 .h 文件,我所做的只是将它们拖到项目中。

在此处输入图像描述

谁能指出我如何更清楚地解释如何执行此操作?我相信它不会像看起来那么难。

4

3 回答 3

13

不幸的是,这是一个不平凡的问题。

原因主要是因为它C++是一种非托管语言C#是一种托管语言。托管和非托管是指语言如何管理内存。

  • C++您必须自己进行内存管理(分配和释放),
  • C# .NET Framework使用垃圾收集器进行内存管理。

在您的图书馆代码中

必须确保所有你调用的地方new,必须调用delete,如果你使用约定,malloc也是如此。freeC

你必须围绕你的函数调用创建一堆包装类,并确保你的C++代码中没有泄漏任何内存。

问题

您的主要问题(据我所知)是您无法直接调用这些函数,C#因为您无法将非托管代码静态链接到托管代码中。

您必须编写一个 .dll 来将所有库函数包装在C++. 完成后,您可以使用C#互操作功能从 dll 调用这些函数。

[DllImport("your_functions.dll", CharSet = CharSet.Auto)]
public extern void your_function();
于 2013-08-09T16:07:36.350 回答
10

您可以做的是创建一个 C++/CLI 包装器并通过包装器公开您想要使用的库的功能。您可以在 C# 项目中轻松引用创建的包装器 dll。这当然需要一些工作来创建托管/非托管包装器,但从长远来看会有所回报。

要创建托管 C++ 项目,请在 C++ 项目模板 CLR 和类库下选择。在这里您可以链接到您的库,按照您习惯的方式使用头文件。

接下来创建一个新类(参考类)并将您的库包装在其中。一个示例可能如下所示:

LibHeader.h

int foo(...);

你写一个像这样的包装类: Header:

Wrapper.h

public ref class MyWrapper
{
    public:
        int fooWrapped();
};

您的实施:

Wrapper.cpp

#include Libheader.h

int MyWrapper::fooWrapped()
{
     return foo();
}

为简单起见,省略了命名空间和所有好东西。现在,您可以在 C# 代码中使用 MyWrapper,就像使用任何其他托管类一样简单。当然,当 lib 的接口变得更复杂时,您必须多考虑一下,但这可能有助于将 lib 代码与您的应用程序分开。希望能对此有所了解。

于 2013-08-09T16:17:21.197 回答
4

它“像看起来一样难”。C++ 和 C# 是矛盾的。第一个具有确定性破坏,第二个没有。现在,您编写 C++/cli 将销毁延迟到由在其自己的线程中工作的垃圾收集器调用的某个终结器,从而在各处引入问题(线程安全,C++ 成员(在 c++/cli 中使用)是否有效?,... )。更糟糕的是,GC 可能会建议 C++ 对象很小(指针)并引发一种内存泄漏(由于延迟释放微小对象)。本质上,您最终会在 C++/cli GC 之上编写 GC,以删除主线程或其他线程中的非 C++/cli (!) 对象。这一切都是疯狂的,...

于 2013-08-09T16:11:15.387 回答