1

I want to use a dll that made by Delphi. It has this function : function CryptStr(str, Key : AnsiString; DecryptStr : boolean) : AnsiString; stdcall;

I copied the Dll in /bin/debug and in application root. my code is :

 [DllImport("Crypt2.dll", EntryPoint = "CryptStr", CallingConvention = CallingConvention.StdCall)]
        static extern string CryptStr( string str,  string Key, bool DecryptStr);
        public string g = "";
        private void Form1_Load(object sender, EventArgs e)
        {
          g=CryptStr("999", "999999", true);
          MessageBox.Show(g);
        }

I have some problem : 1. even I delete Dll from those path application doesn't throw not found exception 2. when application run in g=CryptStr("999", "999999", true); it finishes execution and show the form without running Messagebox line. I tried to use Marshal but above errors remain.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Ehsan Sadeghi
  • 117
  • 1
  • 4
  • 17
  • Form swallows any Exception in the Load Event. You need to handle it yourself in the event. So add a proper try..catch. – Ralf Oct 28 '13 at 10:02

1 Answers1

3

You cannot expect to call that function from a programming environment other than Delphi. That's because it uses Delphi native strings which are not valid for interop. Even if you call from Delphi you need to use the same version of Delphi as was used to compile the DLL, and the ShareMem unit so that the memory manager can be shared. That function is not even well designed for interop between two Delphi modules.

You need to change the DLL function's signature. For example you could use:

procedure CryptStr(
    str: PAnsiChar;
    Key: PAnsiChar;
    DecryptStr: boolean;
    output: PAnsiChar;
); stdcall;

In C# you would declare this like so:

[DllImport("Crypt2.dll")]
static extern void CryptStr(
    string str,
    string Key,
    bool DecryptStr,
    StringBuilder output
);

This change requires the caller to allocate the buffer that is passed to the function. If you want to find examples of doing that, search for examples calling the Win32 API GetWindowText.

If you were using UTF-16 text instead of 8 bit ANSI, you could use COM BSTR which is allocated on the shared COM heap, but I suspect that option is not available to you.

As for your program not showing any errors, I refer you to these posts:

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I think he also can use BSTR/WideString or even OLE TStrings adapter for interop. I guess C# has support for BSTR DLL API ? – Arioch 'The Oct 28 '13 at 11:02
  • @Arioch'The `[MarshalAs(UnmanagedType.BStr)]`, but the issue is that `BSTR` is UTF-16, and the original code is ANSI. So it's a matter of encoding rather than possibility of marshalling. – David Heffernan Oct 28 '13 at 11:04
  • By changing declaration to use `WideString` one makes the conversion automatically. PS: i just have a bias against marker-terminated strings usage for general purposes :-) – Arioch 'The Oct 28 '13 at 12:10
  • @Arioch'The To maintain the same behaviour, you'd have to move the conversion to and from 8 bit into the Delphi code, rather than have it done by the marshaller. – David Heffernan Oct 28 '13 at 12:16
  • Just declaring DLL function parameter WideString insteadof AnsiString does this "move the conversion to and from 8 bit into the Delphi code", doesn't it ? so that is the issue of my comment. – Arioch 'The Oct 28 '13 at 13:37
  • 1
    @Arioch'The Well, so long as the two input strings are assigned to `AnsiString` variables at the top of the function. FWIW, take a look at the comments to my answer to this eerily similar question: http://stackoverflow.com/questions/19634580/call-delphi-dll-function-from-c-sharp So, who knows what this DLL really is!! – David Heffernan Oct 28 '13 at 13:42