带有汇编程序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的字符串。
动态链接库需要一个以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。