Delphi 10编写的DLL在VS2010中调用抛出AccessViolationException异常求助
问题分析与解决方案
你遇到的AccessViolationException是因为C#的函数声明和Delphi DLL的函数定义存在两处关键不匹配,导致内存访问错误,下面具体说明并给出修复方案:
1. 调用约定不匹配
你的Delphi DLL函数声明是stdcall,这是Windows平台常用的调用约定(由被调用方清理栈),但C#代码里的DllImport却指定了CallingConvention.Cdecl(由调用方清理栈),这种不一致会直接导致栈内存损坏,触发保护内存异常。
2. 参数传递方式不匹配
Delphi函数里的参数是var a:Double,这表示参数是传引用(通过指针传递),DLL会期望接收一个Double类型的内存地址;但你在C#里声明的是值类型double a(传值),传递的是数值本身而非内存地址,DLL尝试访问这个错误的内存地址时就会触发异常。
修复后的C#代码
只需要修正调用约定和参数传递方式即可,代码如下:
using System; using System.Windows.Forms; using System.Runtime.InteropServices; namespace TestingImportDLL { public partial class Form1 : Form { // 修正调用约定为StdCall,参数改为ref double以匹配Delphi的var传递 [DllImport("Project2.dll", CallingConvention = CallingConvention.StdCall)] public static extern double showSqRoot(ref double a); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { double numInput, numRes; numInput = Convert.ToDouble(textBox1.Text); // 调用时必须加上ref关键字,传递变量的引用 numRes = showSqRoot(ref numInput); textBox2.Text = numRes.ToString(); } } }
额外注意事项
- 位数一致性:确保C#程序的编译位数(x86/x64)和你使用的Delphi DLL位数完全一致,32位程序只能调用32位DLL,64位同理,位数不匹配也会引发类似的内存异常。
- 参数优化建议:如果你的DLL函数不需要修改传入的
a值(当前代码只是读取a计算平方根),可以把Delphi的函数参数改为const a:Double或者直接去掉var,这样C#里就可以直接传值调用,不需要ref关键字,代码会更简洁。
内容的提问来源于stack exchange,提问作者mehta ankit
相关产品推荐
相关产品推荐

