2

これは呼び出しコードです

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 関数を呼び出してメンバーにデータを入力する必要があります。エラーが発生した場合は、sError からメッセージを取得できます。

この関数を呼び出すにはどうすればよいですか?

私は Delphi に詳しくありません。私の間違いはポインターにあると思います。

以下は私の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は顧客が私に送ったものであり、彼らはソースコードを持っていません.

4

1 に答える 1

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';

などはsStoresMachine入力パラメータを指定する文字列変数です。

1 バイトAnsiCharPAnsiChar. 質問のコードでは、2 バイトの UTF-16CharPChar.

次のように呼び出します。

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応じてレコードを初期化します。

于 2013-04-24T17:11:56.757 に答える