2015-12-03 108 views
1

我使用汇编程序dll编写程序,并试图从汇编程序添加函数到我的c#程序,它将从c#返回字符串中的字符数量。c#汇编程序dll

C#程序:

[DllImport("bibliotekaASM.dll", CallingConvention = CallingConvention.StdCall)] 
     private static extern int zlicz(string tab); 

private void button4_Click(object sender, EventArgs e) 
     { 

      int pom=0; 
      string tab = "1111111fdgsdgdgd"; 

      pom = zlicz(tab); 


     } 

和我的汇编代码:

myprocedure proc 


push ebp 
mov ebp, esp 

mov ebx, [ebp+8]   ; begin of char array 

xor eax, eax 

check: 

cmp byte ptr[ebx],0 ; if end of array 
je endprocedure 
inc ebx 
inc eax 
jmp check 
endprocedure:  

pop ebp 

ret 

myprocedure endp 

,但它仅适用于字符串超过100个元素例如7元这个程序有错误而崩溃:

在GUI.exe中发生未处理的“System.ExecutionEngineException”类型异常

有人可以帮助我解决这个问题,因为我想使用少于100个元素的字符串。

+0

坦率地说,我不知道它是如何工作在*所有*。您的组合代码似乎期待C字符串(以空字符结尾的ASCII字节数组),而不是C#/ .Net“字符串”对象类型。看这里:https://msdn.microsoft.com/en-us/library/22e4dash.aspx – paulsm4

回答

0

动态链接库需要一个空终止的ANSI字符串,你逝去的前缀BSTR

按照MSDN documentation, Default Marshaling for Strings,以下签名的长度:

DllImport("bibliotekaASM.dll", CallingConvention = CallingConvention.StdCall)] 
private static extern int myprocedure(string tab); 

将元帅字符串变量选项卡, UnmanagedType.BStr

根据此表,但:

UnmanagedType.BStr (default) 
    A COM-style BSTR with a prefixed length and Unicode characters. 
UnmanagedType.LPStr 
    A pointer to a null-terminated array of ANSI characters. 
UnmanagedType.LPWStr 
    A pointer to a null-terminated array of Unicode characters. 

你需要的是当元帅的标签变量UnmanagedType.LPStr

这可以很容易地实现:

DllImport("bibliotekaASM.dll", CallingConvention = CallingConvention.StdCall)] 
private static extern int myprocedure([MarshalAs(UnmanagedType.LPStr)] string tab); 

然而,

这将封送字符串作为每个字符一个字节,这意味着,您传递的是ANSI字符串,并且不支持unicode。

为支持Unicode字符,只需将非托管类型说明更改为UnmanagedType.LPWStr

DllImport("bibliotekaASM.dll", CallingConvention = CallingConvention.StdCall)] 
private static extern int myprocedure([MarshalAs(UnmanagedType.LPWStr)] string tab); 

在这种情况下,但是,你也应该更新汇编代码读取Unicode字符(我可以想像不是一个简单的任务)

注意:我通过使用MASM32编译dll并从C#中调用dll并且成功测试了提议的解决方案LPStr来再现了这个问题。

+0

谢谢你的帮助,但它仍然无法正常工作。添加[MarshalAs(UnmanagedType.LPWStr)]没有区别,但它仍然不适用于少于128个元素的字符串。你在asm代码中改变了一些寄存器吗?我不知道发生了什么;/ – alok123

+0

但它在我的机器上工作。你能不能也请分享异常的完整堆栈跟踪? –

+0

因为我没有在GUI中发生'System.ExecutionEngineException'。exe,我只是得到一个异常,访问冲突(0x0000005)时试图你的方式。 –