如何在C#中使用Delphi的Dll(用PChar类型型) [英] How to use Delphi Dll(with PChar type) in C#

查看:461
本文介绍了如何在C#中使用Delphi的Dll(用PChar类型型)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是德尔福DLL的代码:

Here is the Delphi DLL code:

library Project2;

uses
  SysUtils,
  Classes;

{$R *.res}

function SimpleConv(const s: string): string;
var
  i: Integer;
begin
  Result := '';
  for i := 1 to Length(s) do
    if Ord(S[i]) < 91 then
      Result := Result + S[i];
end;

function MsgEncode(pIn: pchar; InLen: Integer; var pOut: pchar; var OutLen: Integer): Boolean; stdcall;
var
  sIn: string;
  sOut: string;
begin
  SetLength(sIn, InLen);
  Move(pIn^, sIn[1], InLen);

  sOut := SimpleConv(sIn);   // Do something

  OutLen := Length(sOut);
  GetMem(pOut, OutLen);
  Move(sOut[1], pOut^, OutLen);
  Result := OutLen > 0;
end;

procedure BlockFree(Buf: pchar); stdcall;
begin
  if assigned(Buf) then
     FreeMem(Buf);
end;

exports
  MsgEncode,
  BlockFree;

begin
end.



DLL函数MsgEncode将allocmem噘嘴参数,并且BlockFree用于释放其中alloced内存由MsgEncode

The Dll function MsgEncode will allocmem to pOut param, and the BlockFree is used to free the memory which alloced by MsgEncode.

我的问题是:如何使用这个DLL在C#中?我在C#中的新手。

推荐答案

我打算把你的面值的问题,与一些附带条件:

I'm going to take your question at face value, with a few provisos:


  • 无论您使用的是Unicode的德尔福与否是至关重要的使用要知道互操作的代码 PChar类型,因为 PChar类型 属于ANSIChar 之间浮动和 WideChar 根据德尔福的版本。我假定你使用Unicode德尔福。如果没有,那么你需要改变字符串为P编组/调用方。

  • 我修改您的DLL的代码。我已删除了长度参数和我的工作,前提是,你只打算让受信任的代码调用此DLL。不可信代码可能会产生缓冲区溢出,但你不会让你的机器上运行不受信任的代码,是吗?

  • 我也改变了 BlockFree ,以便它可以接收一个无类型指针。没有必要为它是类型为 PChar类型,它只是调用免费

  • Whether you are using a Unicode Delphi or not is essential to know for interop code using PChar because PChar floats between AnsiChar and WideChar depending on the version of Delphi. I've assumed that you use Unicode Delphi. If not then you'd need to change the string marshalling at the P/Invoke side.
  • I've modified your DLL code. I've removed the length parameters and am working on the assumption that that you are only going to let trusted code call this DLL. Untrusted code could produce buffer overruns but you aren't going to let untrusted code run on your machine, are you?
  • I've also changed BlockFree so that it can receive an untyped pointer. There's no need for it to be types as PChar, it's just calling Free.

下面是修改后的Delphi代码:

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.

和这里的另一边的C#代码:

And here's the C# code on the other side:

使用System.Runtime.InteropServices
;

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

这应该让你开始。既然你是新的C#中,您将需要做的的P / Invoke读了不少。尽情享受吧!

This should get you started. Since you are new to C# you are going to need to do quite a bit of reading up on P/Invoke. Enjoy!

这篇关于如何在C#中使用Delphi的Dll(用PChar类型型)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆