带有汇编程序dll的c#

本文关键字:dll 汇编程序 | 更新日期: 2023-09-27 18:25:22

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

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的字符串。

带有汇编程序dll的c#

动态链接库需要一个以null结尾的ansi字符串,而您正在传递一个以长度为前缀的BSTR

根据MSDN文档,字符串的默认封送,以下签名:

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#调用它来重现这个问题,并成功地测试了所提出的解决方案LPStr。