Leo*_*Leo 3 .net c# delphi pinvoke
这是Delphi DLL代码:
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.
Run Code Online (Sandbox Code Playgroud)
Dll函数MsgEncode将allocmem分配给pOut param,而BlockFree用于释放由MsgEncode分配的内存.
我的问题是:我怎样才能在C#中使用这个dll?我是C#的新手.
我将以面值来回答您的问题,并附带几个附带条件:
PChar
因为PChar
浮动之间AnsiChar
和WideChar
取决于Delphi的版本.我假设您使用Unicode Delphi.如果没有,那么你需要在P/Invoke端更改字符串编组.BlockFree
了它,它可以接收一个无类型的指针.没有必要将它作为类型PChar
,它只是调用Free
.这是修改后的Delphi代码:
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.
Run Code Online (Sandbox Code Playgroud)
这是另一方的C#代码:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这应该让你开始.由于您是C#的新手,因此您需要在P/Invoke上进行相当多的阅读.请享用!
归档时间: |
|
查看次数: |
12106 次 |
最近记录: |