在C#WPF应用程序中使用外部C ++ DLL

时间:2016-02-18 22:19:57

标签: c# c++ wpf dll

完全披露......我是C / C ++ / C #newb。 我一直在玩我的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 fuzzy.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)

2 个答案:

答案 0 :(得分:1)

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

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

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

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

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

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

答案 1 :(得分:1)

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

我强烈建议你让Adam Nathans出色的书,详细介绍pinvoke http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X

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