how to consume delphi dll in c #

2

I have a delphi function that I export as dll, here I leave my code:

library MdEncDec;

uses
  System.SysUtils,
  System.Classes,
  Bcrypt;

{$R *.res}

function EncryptWord( value: PChar ): ShortString; stdcall; export;
var
  BCRYPT1: TBCRYPT;
begin
  BCRYPT1 := TBCRYPT.create( nil );
  try
    BCRYPT1.AlphaMode := False;
    BCRYPT1.AlphaMode := True;
    BCRYPT1.Mode      := MODE_ENCRYPT;
    BCRYPT1.InString  := value;
    Result            := BCRYPT1.OutString;
  finally
    BCRYPT1.Free;
  end;
end;

function DecryptWord( value: PChar ): ShortString; stdcall; export;
var
  BCRYPT1: TBCRYPT;
begin
  BCRYPT1 := TBCRYPT.create( nil );
  try
    BCRYPT1.AlphaMode := False;
    BCRYPT1.AlphaMode := True;
    BCRYPT1.Mode      := MODE_DECRYPT;
    BCRYPT1.InString  := value;
    Result            := BCRYPT1.OutString;
  finally
    BCRYPT1.Free;
  end;
end;

exports EncryptWord, DecryptWord;

begin
end.

At the time of consuming it in c # I did the following:

 [DllImport("MdEncDec.dll", CharSet = CharSet.Unicode, CallingConvention
 =CallingConvention.StdCall)]
 public static extern string 
 EncryptWord([MarshalAs(UnmanagedType.LPWStr)] string cadena);

 Console.WriteLine(EncryptWord("Test"));
 Console.ReadLine();

This gives me problems does not show me the encrypted string that is the function of the delphi, at the end it does not show me anything, I already compile the 32 and 64 bit dll in debug and release mode I do not know what else to do, if someone has knowledge about this and you could help me, I'd appreciate it, I've been here a week.

Thanks

    
asked by Raidel Fonseca 07.11.2018 в 19:24
source

1 answer

1

Your problem lies in the use of data type ShortString as the output type of the functions you are exporting.

This is because this is a type of data that only exists in pascal and that has a particular behavior.

At first glance, for a quick test, you can substitute the output types for AnsiString and still you will have the problem of who reserves and who releases the memory.

As a definitive solution, change it by a pointer to an array of characters, such as PChar , PAnsiChar or PWideChar , and whoever calls this routine is responsible for reserving and releasing this memory.

function EncryptWord(Value: PChar): PChar; stdcall; export;

Why is not its use recommended?

Informatively, the implementation details are that the position [0] of the array, saves the length of the character string (so it can have a maximum length of 255 characters), and the string is not terminated in #0

This is why it is not recommended to use it in DLL's that are going to be consumed from other environments, less .NET.

Technically it could be used, but you would be forced to implement the logic to handle this type of strings in the language of your choice. It is not complicated, but it does not make sense beyond a purely academic interest.

    
answered by 09.11.2018 в 22:47