这是调用代码
unit CY;
interface
uses windows;
type
TMember_Rd = Record
iID: integer;
sCode: Array[0..255] of char;
sName: Array[0..255] of char;
end;
PTMember_Rd = ^TMember_Rd;
function GetMember(sStore, sMachine: PChar; const sTrack, sCode, sVerify: PChar;
Member: PTMember_Rd; sError: PChar): Integer; stdcall; external 'Interface.dll';
implementation
end.
我需要调用GetMember函数并将数据填充到Member中,如果有任何错误,我可以从sError获取消息。
如何调用此功能?
我不熟悉德尔福;我认为我的错误在于指针。
以下是我的c#代码正常工作
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace JFTest
{
public class JFService
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct PTMember_Rd
{
public Int32 id;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string sCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string sName;
}
[DllImport("Interface.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int GetMember(StringBuilder sStore, StringBuilder sMachine, StringBuilder sTrack, StringBuilder sCode, StringBuilder sVerify, ref PTMember_Rd Member, [MarshalAs(UnmanagedType.LPStr)] string sError);
}
}
我没有其他的代码,dll是客户发给我的,他们没有源代码。
答案 0 :(得分:1)
我认为你的p / invoke代码是错误的。您说Member
和sError
是输出参数,其他参数是输入。在这种情况下,p / invoke应该是:
[DllImport("Interface.dll", CharSet=CharSet.Ansi)]
public static extern int GetMember(
string sStore,
string sMachine,
string sTrack,
string sCode,
string sVerify,
ref PTMember_Rd Member,
StringBuilder sError
);
假设这是正确的,Delphi应该如下所示:
type
TMember_Rd = Record
iID: integer;
sCode: Array[0..255] of AnsiChar;
sName: Array[0..255] of AnsiChar;
end;
function GetMember(
sStore: PAnsiChar;
sMachine: PAnsiChar;
sTrack: PAnsiChar;
sCode: PAnsiChar;
sVerify: PAnsiChar;
out Member: TMember_Rd;
sError: PAnsiChar
): Integer; stdcall; external 'Interface.dll';
其中sStore
,sMachine
等是指定输入参数的字符串变量。
我们需要使用一个字节AnsiChar
和PAnsiChar
。问题中的代码使用两个字节的UTF-16 Char
和PChar
。
你会这样称呼:
var
sError: AnsiString;
Member: TMember_Rd;
retval: Integer;
....
SetLength(sError, 256);
retval := GetMember(
PAnsiChar(AnsiString(sStore)),
PAnsiChar(AnsiString(sMachine)),
PAnsiChar(AnsiString(sTrack)),
PAnsiChar(AnsiString(sCode)),
PAnsiChar(AnsiString(sVerify)),
Member,
PAnsiChar(AnsiString(sError))
);
我不知道需要制作sError
字符串的大小。如果您没有任何文档,则无法找到。更好地使它变大并希望最好。如果你没有足够大,并且该函数试图写入该缓冲区,那么你有缓冲区溢出。
我认为Member
参数具有纯粹的语义,因为这就是你所说的。如果您需要使用部分或全部字段传递数据,请将其更改为var
并相应地初始化记录。