Search code examples
c#delphipinvokedllimport

DLLImport get Attempted to read or write protected memory


I'm going crazy.

I have a dll, with this function :

function MyFunc(myId: integer; var LstCB: array of char): integer; stdcall;

The first parameter is a poor integer. But the second one is a char[2048] which get someting like this

('9', #13, #10, '8', '8', '8', '8', '0', '0', '0', '0', '0', '0', '0', '0', '2', '5', '0', '7', #13, #10, '8', '8', '8', '8', '0', '0', '0', '0', '0', '0', '0', '0', '2', '6', '0',  #13, #10, '8', '8', '8', '8', '0', '0', '0', '0', '0', '0', '0', '0', '3', '3', '1', '5', #13, #10, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0,....#0)

I imported this with DllImport :

[DllImport(@"MyDll.dll", EntryPoint = "MyFunc", CallingConvention = CallingConvention.StdCall)]
internal static extern int MyFunc(int myId, string list);

And I get :

Attempted to read or write protected memory. This is often an indication that other memory has been corrupted.

Have you some ideas please ???

Thanks.


Solution

  • Your Delphi function is using an open array for the string parameter. This is not something that should be exposed across a DLL boundary. The protocol for calling an Delphi open array is implementation specific.

    You should change your Delphi code to receive a PChar.

    function MyFunc(myId: Integer; LstCB: PChar): Integer; stdcall;
    

    If the data is being passed from C# to the Delphi DLL then your P/invoke is fine. If the DLL is meant to return data to the C# code then you need to declare the text parameter as StringBuilder in the P/invoke.

    [DllImport(@"MyDll.dll", EntryPoint = "MyFunc", CallingConvention = CallingConvention.StdCall)]
    internal static extern int MyFunc(int myId, StringBuilder list);
    ...
    StringBuilder list = new StringBuilder(2048);
    int res = MyFunc(ID, list);
    string theList = list.ToString();
    

    The only other thing to watch out for is what the meaning of char is in Delphi. If the DLL is built with Delphi 2009 or later then char is a Unicode character and you need to specify the CharSet in your P/invoke.