我正在尝试在ssdeep fuzzy.dll上调用方法
具体来说,我试图称这种方法....
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如果我忽略警告,那么呼叫似乎成功,所以我必须靠近)
为了实现这一目标,我需要对我的定义做出哪些改变?
答案 0 :(得分:3)
我在MSDN forums找到了有同样问题的人:
- 关于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 ++编译器的名称损坏。
答案 1 :(得分:1)
接受的答案似乎解决了原始提问者的问题,但c#中的等效代码对我不起作用。在尝试了越来越复杂的注释之后,回归基础最终确实有效。对于每个人的参考,我包括三个接口函数和工作代码的声明(针对ssdeep version 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