"试图读取或写入受保护的内存.这通常表明其他内存已损坏." 来自C#的Delphi7 DLL

use*_*061 4 c# delphi dll

我在使用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.
Run Code Online (Sandbox Code Playgroud)

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

任何帮助将得到真正的赞赏

Mic*_*eld 7

编辑:

请注意,经过进一步的反思,我很确定这不是正确的答案.使用不匹配的调用约定(因此我最初的直觉就是问题)仍然是一个坏主意,但在这种情况下,它可能不是GPF的原因.

原版的:

99%的情况下,此错误意味着您的调用约定错误.自从我在Delphi写作以来已经有一段时间,但我认为这将解决您的问题:

procedure moveforward; export; stdcall;
Run Code Online (Sandbox Code Playgroud)

调用约定通常不是当你只使用一个单一的编译器的问题,因为一切都使用相同的一个.混合语言时,或者即使混合使用不同供应商的编译器,也可能会出现问题.调用约定确定调用的哪一端必须清理参数; 如果双方都试图这样做,那很可能会导致GPF.

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

  • **非常好**编辑.:)如果可以的话,我会额外给它+1.(我只会更改"不幸"和"不支持"这两个词,因为在你编写原生Win32应用程序的大多数情况下,`fastcall`或`register`是最好的选择 - 你可以说微软选择`stdcall `作为默认值是"不幸",因为它没有以某种方式使用时的"fastcall"效率.)Delphi的主要用途是开发独立的,自包含的Win32可执行文件,并且使用` fastcall`或`register`调用约定.:) (4认同)
  • +1.您可能希望编辑以解释应将`stdcall`添加到所有导出的过程声明中(因为提问者已明确表示他们不熟悉Delphi). (2认同)

Rob*_*edy 5

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

procedure set_up_dll; stdcall; export;
begin
  com1 := TComport.Create(nil);
end;
Run Code Online (Sandbox Code Playgroud)

还有另一个摧毁它:

procedure clean_up_dll; stdcall; export;
begin
  com1.Free;
  com1 := nil;
end;
Run Code Online (Sandbox Code Playgroud)

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