【问题标题】:Using an External C++ DLL in C# WPF application在 C# WPF 应用程序中使用外部 C++ DLL
【发布时间】:2016-02-18 22:19:57
【问题描述】:

完全披露...我是 C/C++/C# 新手。 我一直在我的 linux 机器上玩 ssdeep (http://ssdeep.sourceforge.net/)。

Python 包装器运行良好 (https://python-ssdeep.readthedocs.org/en/latest/usage.html)。我现在正在尝试编写一个使用该库的 Windows GUI 应用程序 (C# WPF)。在 Windows 二进制下载中,有许多文件,包括 DLL 和 DEF 文件。

在API.TXT文件中,作者写道:

Windows ssdeep 软件包包括一个 Win32 DLL 和一个 .def 文件。 虽然 MSVC 用户不能直接使用 DLL,但他们可以轻松创建 使用 Microsoft LIB 工具的 .lib 文件:

C:> lib /machine:i386 /def:fuzzy.def

然后您可以使用生成的库编译您的程序:

C:> cl sample.c 模糊.lib

我已经这样做了,我现在有fuzzy.dllfuzzy.deffuzzy.expfuzzy.lib。经过多次谷歌搜索,我不确定如何在我的 WPF 应用程序中实际使用这些文件。

在我的解决方案中我应该把它放在哪里(无论我需要什么文件)?我需要使用using System.Runtime.InteropServices; 吗?最好,我会在我的代码中打包这个 dll 或 lib,这样它就不是外部依赖项,但此时,我很乐意调用库中的函数。

编辑:

我找到了this old link,它给了我这个代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;


namespace FuzzyBear
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {


        [DllImport("fuzzy.dll")]
        public static extern int fuzzy_hash_filename([MarshalAs(UnmanagedType.LPStr)] string fname, [MarshalAs(UnmanagedType.LPStr)] string result);


        [DllImport("fuzzy.dll")]
        public static extern int fuzzy_compare(string sig1, string sig2);


public MainWindow()
        {
            string result = "";
            int test = fuzzy_hash_filename("C:\\dev\\tools\\ssdeep-2.13\\API.txt", result);
            System.Diagnostics.Debug.Write("Lookie here: ");
            System.Diagnostics.Debug.WriteLine(test.ToString());
            InitializeComponent();
        }
    }
}

这给了我这个错误:

Additional information: A call to PInvoke function 'FuzzyBear!FuzzyBear.MainWindow::fuzzy_hash_filename' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

签名不匹配是什么意思?这是否意味着我的函数输入与header file's 输入不匹配?这些是来自 cpp 头文件的函数:

int     fuzzy_hash_filename (const char *filename, char *result)
int     fuzzy_compare (const char *sig1, const char *sig2)

【问题讨论】:

    标签: c# c++ wpf dll


    【解决方案1】:

    您无法像使用 C++ 那样链接到 C# 中的静态库,因此您无法将代码打包在一起。为了使用你的库,你需要一个 Win32 DLL - 如果你只有一个 .lib,你需要为它创建一个包装 DLL。

    如果您确实有一个有效的 Win32 DLL,您可以使用 P/Invoke 从 C# 调用 C++ DLL 上的方法。

    为此,您需要使用 DllImport 声明要使用的每个 C++ 方法。我无法为您提供确切的语法,因为它取决于您想从 DLL 中使用的方法。一个例子是:

    DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)] static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);

    在 [http://www.pinvoke.net] 有一个标准 Win32 DLL 的 DllImport 声明库,应该可以帮助您入门。

    一旦声明,您就可以像在 .Net 中一样调用方法。问题是你如何处理不同数据类型的编组——你需要了解如何使用 IntPtr。

    【讨论】:

      【解决方案2】:

      你有一个 DLL。需要使用 PInvoke 调用其中的方法。

      我强烈建议您购买 Adam Nathans 的优秀书籍,其中详细介绍了 pinvoke http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X

      教程中的 Pinvoke 很简单,但在现实生活中可能会变得复杂。这取决于方法签名

      【讨论】:

      • 谢谢,我去看看那本书。
      猜你喜欢
      • 1970-01-01
      • 2018-07-23
      • 1970-01-01
      • 2012-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      相关资源
      最近更新 更多