Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Attempted to read or write protected memory. This is often an indication that other memory is corrupt." Delphi7 DLL from C#

Tags:

c#

dll

delphi

I am facing a problem calling a Delphi 7 DLL file from C#. I am new to C# and don't know Delphi that much and I don't need to really knows that much. I just need to get this problem solved as soon as possible.

I am trying to call the dll from C# but I get this error : "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

And I have no clue why it is happening . As you will see in my Delphi code , I'm not trying to return any value . I just need to send some commands on the COM port. Please if anyone can help me out of here :(

Delphi DLL code:

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# Code

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();
        }
    }
}

Any help will be truly appreciated

like image 798
user1184061 Avatar asked Dec 17 '22 04:12

user1184061


1 Answers

EDIT:

Please note, upon further reflection I'm pretty sure this is not the right answer. It's still a bad idea to use mismatched calling conventions (thus my initial instinct that it was the problem) but in this case it is probably not the cause of the GPF.

ORIGINAL:

99% of the time, this error means you got the calling conventions wrong. It's been a while since I wrote in Delphi but I think this will fix your problem:

procedure moveforward; export; stdcall;

The calling convention is normally not an issue when you're only using a single compiler, because everything uses the same one. It can be a problem when you mix languages, or even if you mix different vendor's compilers. The calling convention determines which end of the call has to clean up parameters; if both sides try to do that it's likely to cause a GPF.

By default, the DllImport attribute uses a calling convention of CallingConvention.StdCall, though you can override that in the attribute itself. Unfortunately, Delphi's default calling convention is a type that isn't supported (alternatively called fastcall or register), so your only option is to change the Delphi side to use stdcall.

like image 61
Michael Edenfield Avatar answered May 12 '23 07:05

Michael Edenfield