4

以前に、保護されたメモリ エラーの読み取りまたは書き込みを試みたことを見たことがあります。通常、c# 構造体を正しく設定しないと、エラーが表示されます。他の通話は正常に機能していますが、これは連携していません。関数呼び出しと構造体の両方が問題を引き起こしている可能性があることはほぼ確実です。

C 構文

int CardTransaction(pTRequest req, char *ProductCodes)

リクエストの構造 (繰り返しのデータ型があったため、要約しました)

typedef struct _cardRequest
{
  unsigned short RedemptionNum
  long TotalAmount;
  unsigned char filler1[257];
  char CardNumber[80];
  unsigned char cardType;
} TRequest, *pTRequest;

C# 関数呼び出し

[DllImport("card.dll"), CallingConvention.Cdecl, CharSet = CharSet.Auto)]
public static extern int CardTransaction(ref CardRequest cardRequest, [MarshalAs(UnManagedType.LPStr)] StringBuilder productCodes);

ProductCodes は null なので、何も入っていない stringbuilder オブジェクトをインスタンス化し、それを渡しました。これは私が問題になる可能性があると私が考えている1つの場所です。

C# 構造

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]    
public struct CardRequest
{
  public uint16 RedemptionNum

  public int TotalAmount;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]
  public string filler1;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
  public string CardNumber;

  public byte cardType;

} 
4

1 に答える 1

2

明らかな問題は、C コードが整列された構造体を使用しているのに、何らかの理由で C# 構造体をパックすることを選択したことです。Pack = 1C# コードから を削除して、2 つの構造を一致させます。

それを超えると、フィラー配列は文字列というよりもバイト配列のように見えます。私は次のように宣言します:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 257)]
public byte[] filler1;

パラメータに渡したい場合はnullproductCodesそれができると思います。私は自分でそれをすべて思い出すことはできませんが、通常、nullap/invoke に渡すと、マーシャラーはNULLネイティブ コードに渡します。

于 2013-10-08T23:51:51.563 に答える