1

我正在尝试调用 ssdeep blur.dll 上的方法

.h文件在这里友好的参考在这里

具体来说,我正在尝试调用此方法....

int fuzzy_hash_filename (
        const char * filename,
        char * result 
)   

我有以下...

<DllImport("C:\SSDeep\Fuzzy.dll", EntryPoint:="fuzzy_hash_filename")>
Private Shared Function fuzzy_hash_filename(
                                           <InAttribute(),
                                           MarshalAsAttribute(UnmanagedType.LPStr)>
                                           ByVal Filename As String, ByVal Result As StringBuilder) As Integer
End Function


Public Shared Function FuzzyHash(Filename As String) As String
    Dim Ret As New StringBuilder
    Ret.Capacity = NativeConstants.FUZZY_MAX_RESULT
    Dim Success = fuzzy_hash_filename(Filename, Ret)
    If Success <> 0 Then
        Throw New Exception("SSDeep fuzzy hashing failed")
    End If
    Return Ret.ToString
End Function

如果我运行这段代码,VS 会给我一个模态对话

调用 PInvoke 函数 '(Blah)::fuzzy_hash_filename' 使堆栈失衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。

(FWIW 如果我忽略警告,呼叫似乎成功,所以我必须关闭)

我需要对我的定义进行哪些更改才能实现这一目标?

4

2 回答 2

3

我在MSDN 论坛上发现了一个有同样问题的人:

  1. 关于 PInvokeStackImbalance。

1.1 这通常是由于 API 使用的调用约定与 C# 代码中为 API 声明的调用约定不匹配。

1.2 默认情况下,如果未设置 DllImportAttribute 的 CallingConvention 参数,则默认使用 StdCall。

1.3 如果 DoSomething() API 要使用 __cdecl(在 C++ 项目中是默认的),那么您应该在 C# 代码中为 DoSomething() 使用以下声明: [DllImport(@"dll.dll", CallingConvention=CallingConvention .Cdecl)]

1.4 另外,我建议您将 API 声明为 extern "C",否则它将受到 C++ 编译器的名称修改。

于 2012-08-07T09:20:02.897 回答
1

接受的答案似乎已经解决了原始提问者的问题,但是 c# 中的等效代码对我不起作用。在尝试了越来越复杂的注释之后,回归基础最终确实奏效了。供大家参考,我包括三个接口函数和工作代码的声明(针对ssdeep 版本 2.9构建)。

    //Note: StringBuilder here is the standard way to do it, but is a perf hit because unicode stringbuilder can't be pinned when martialling char*.
    //See http://msdn.microsoft.com/en-us/magazine/cc164193.aspx#S4

    //int fuzzy_hash_buf(const unsigned char *buf, uint32_t buf_len, char *result)
    [DllImport("fuzzy.dll")]
    public static extern int fuzzy_hash_buf(StringBuilder buf, int buf_len, StringBuilder result);

    //int fuzzy_hash_filename(const char* filename, char* result)   
    [DllImport("fuzzy.dll")]
    static extern int fuzzy_hash_filename(string filename, StringBuilder result); 

    //int fuzzy_compare (const char *sig1, const char *sig2)
    [DllImport("fuzzy.dll")]
    static extern int fuzzy_compare(string sig1, string sig2); 

    static void Main(string[] args)
    {
        StringBuilder buf = new StringBuilder("test");
        StringBuilder result0 = new StringBuilder(150);
        fuzzy_hash_buf(buf, 4, result0);
        Console.WriteLine(result0);

        string filename = "test.txt";
        StringBuilder result1 = new StringBuilder(150);
        fuzzy_hash_filename(filename, result1);
        Console.WriteLine(result1);

        int matchScore = fuzzy_compare(result0.ToString(), result1.ToString());
        Console.WriteLine("MatchScore: " + matchScore);
    }

输出:

ssdeeptest.exe 3:Hn:Hn 24:gRnIM7stweRp+fEWU1XRk+/M98D6Dv3JrEeEnD/MGQbnEWqv3JW:gRIMwtrMU1Bk2I3Jrg53JW MatchScore: 0

于 2012-08-31T16:21:24.677 回答