"Attempted to read or write protected memory. This is often an indication that other memory is corr



我在从C#调用Delphi 7 DLL文件时遇到问题。我是C#的新手,对Delphi了解不多,也不需要真正了解那么多。我只需要尽快解决这个问题。

我正试图从C#调用dll,但我收到了以下错误:"试图读取或写入受保护的内存。这通常表明其他内存已损坏。"

我不知道为什么会发生这种事。正如您将在我的Delphi代码中看到的,我没有试图返回任何值。我只需要在COM端口上发送一些命令。如果有人能帮我离开这里,请:(

Delphi DLL代码:

library Project2;

uses
  SysUtils,
  ComPort,
  Classes;
var com1:TComport ;
{$R *.res}
procedure moveforward; export;
begin
  com1.WriteAnsiString('#20 P1528 CR'+sLineBreak);
  com1.WriteAnsiString('#7 P1465 CR'+sLineBreak);
end;
procedure movebackward; export;
begin
  comport1.WriteAnsiString('#7 P1528 CR'+sLineBreak);
  comport1.WriteAnsiString('#20 P1465 CR'+sLineBreak);
end;
procedure stopmove;export;
begin
  comport1.WriteAnsiString('#20 P1500 CR'+sLineBreak);
  comport1.WriteAnsiString('#7 P1500 CR'+sLineBreak);
end;
procedure catch; export;
begin
  comport1.WriteAnsiString('#2 P2120 T2000 CR'+sLineBreak); //arm
  comport1.WriteAnsiString('#30 P2260 T500 CR'+sLineBreak); //gripper
end;
procedure initialize; export;
begin
  comport1.WriteAnsiString('#2 P2184 T1000 CR'+sLineBreak); //arm
  comport1.WriteAnsiString('#30 P1980 T2000 CR'+sLineBreak); //gripper
end;
exports  
  moveforward, movebackward, stopmove, catch, initialize;
begin
end.

C#代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        [System.Runtime.InteropServices.DllImport("Project2.dll")]
        public static extern void moveforward();
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            moveforward();
        }
    }
}

任何帮助都将不胜感激

编辑:

请注意,经过进一步思考,我确信这不是正确的答案。使用不匹配的调用约定仍然是个坏主意(因此我最初认为这是问题所在),但在这种情况下,这可能不是GPF的原因。

原件:

99%的情况下,这个错误意味着您的调用约定是错误的。我已经有一段时间没有在Delphi上写了,但我认为这会解决你的问题:

procedure moveforward; export; stdcall;

当您只使用单个编译器时,调用约定通常不是问题,因为所有编译器都使用相同的编译器。当您混合语言时,甚至当您混合不同供应商的编译器时,这都可能是一个问题。调用约定确定调用的哪一端必须清理参数;如果双方都试图这样做,很可能会引发GPF。

默认情况下,DllImport属性使用CallingConvention.StdCall的调用约定,不过您可以在属性本身中重写该约定。不幸的是,Delphi的默认调用约定是一种不受支持的类型(或者称为fastcall或register),因此您唯一的选择是将Delphi端更改为使用stdcall。

Delphi代码从不为全局com1变量赋值。您需要使它引用一个TComport实例。导出另一个设置DLL以供进一步使用的函数:

procedure set_up_dll; stdcall; export;
begin
  com1 := TComport.Create(nil);
end;

有另一个摧毁它的:

procedure clean_up_dll; stdcall; export;
begin
  com1.Free;
  com1 := nil;
end;

在使用DLL的其他函数之前和之后调用这些函数。

相关内容

最新更新