I am going to take your question at par, with a few caveats:
- If you use Unicode Delphi or not, it is important to know the interaction code using
PChar , because PChar floats between AnsiChar and WideChar depending on the version of Delphi. I assumed that you are using Unicode Delphi. If not, you will need to change the string sorting on the P / Invoke side. - I changed your dll code. I have deleted the length parameters and work under the assumption that you are only going to allow trusted code to call this DLL. Incorrect code can cause buffer overflows, but you are not going to run untrusted code on your computer, are you?
- I also modified
BlockFree so that it can get an untyped pointer. There is no need for him to be a type of PChar , he just called Free .
Here's the modified Delphi code:
library Project2; uses SysUtils; {$R *.res} function SimpleConv(const s: string): string; begin Result := LowerCase(s); end; function MsgEncode(pIn: PWideChar; out pOut: PWideChar): LongBool; stdcall; var sOut: string; BuffSize: Integer; begin sOut := SimpleConv(pIn); BuffSize := SizeOf(Char)*(Length(sOut)+1);//+1 for null-terminator GetMem(pOut, BuffSize); FillChar(pOut^, BuffSize, 0); Result := Length(sOut)>0; if Result then Move(PChar(sOut)^, pOut^, BuffSize); end; procedure BlockFree(p: Pointer); stdcall; begin FreeMem(p);//safe to call when p=nil end; exports MsgEncode, BlockFree; begin end.
And here is the C # code on the other hand:
using System; using System.Runtime.InteropServices;
namespace ConsoleApplication1 { class Program { [DllImport("project2.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool MsgEncode(string pIn, out IntPtr pOut); [DllImport("project2.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] public static extern void BlockFree(IntPtr p); static void Main(string[] args) { IntPtr pOut; string msg; if (MsgEncode("Hello from C#", out pOut)) msg = Marshal.PtrToStringAuto(pOut); BlockFree(pOut); } } }
This should help you get started. Since you're new to C #, you will need to read a little P / Invoke. Enjoy it!
source share