You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:51:37