0

C++ dll にある次のメソッドを C# から呼び出すにはどうすればよいですか? 次の構造を C# で再作成するにはどうすればよいですか?


オリジナル

方法:

LONG MyMethod (P_HOLO_INFO pInfo, LPVOID pBuffer, LPUSHORT pTracksWritten);

構造:このメソッドは、次の構造を使用します。

typedef struct _HOLO_INFO
{
    LONG     lHoloType;
    LONG     lStatus;
    HANDLE   lThreadHandle;
    LONG     lErrorCode;
    LONG     lDriveIndex;
    LONG     lHeight;
    SHORT    iFormat;
    INT      iStartingTrack;
    LONG     lWrite;
    LONG     lSkip;
    BOOL     bSkipZero;
    BOOL     bInvert;
    LONG     lMaxConsecutiveErrors;
    LONG     lMaxTotalErrors;
    LONG     lMostConsecutiveErrors; 
    LONG     lTotalErrors;
    LPBYTE   pBuffer;
    LPUSHORT pTracksWritten;
    LONG     bUpsideDown;
} HOLO_INFO, *P_HOLO_INFO;

私はこのようにC#で働いた

方法:

[DllImport("My.dll", EntryPoint = "_MyMethod@12")]
public unsafe static extern long MyMethod(ref HOLO_INFO pInfo, Byte[] pBuffer,ref ushort pTracksWritten);

構造:

このメソッドは、次の構造を使用します。

unsafe public  struct HOLO_INFO 
{
    public long  lHoloType;
    public long  lStatus;
    public long  lThreadHandle;
    public ulong lErrorCode;
    public long  lDriveIndex;
    public long  lHeight;
    public short iFormat;
    public int   iStartingTrack;
    public long  lWrite;
    public long  lSkip;
    public bool  bSkipZero;
    public bool  bInvert;
    public long  lMaxConsecutiveErrors;
    public long  lMaxTotalErrors;
    public long  lMostConsecutiveErrors; 
    public long  lTotalErrors;
    public Byte* pBuffer;
    public long* pTracksWritten;
    public long  bUpsideDown;
};

次のようにメソッドを呼び出しました。

  do
  {
    result = MyMethod(ref pInfo,ptrBuf,pTracksWritten);
  } while (result ==1 );

なぜなら、アクティブであれば 0、正常に完了した場合は 1、エラーで停止した場合は 3 を返すからです。メソッドが実行中の状態 (Active-1) の場合。pInfopTracksWrittenを変更して、ステータス情報を更新します。

4

3 に答える 3

3

多くの問題:

  • LONG は C# では int として宣言する必要があります
  • HANDLE は IntPtr です。
  • pTracksWritten がありません。おそらくそれを作成する必要があり、IntPtr である pBuffer と Marshal.AllocHGlobal を使用してそれらにメモリを割り当てる必要があります。
  • Cdecl を使用するには、[DllImport] 宣言に CallingConvention が必要です。

アンマネージ コードをデバッグできない場合、これが機能する可能性は高くありません。基本的なサニティ テストの 1 つは、Marshal.SizeOf() がアンマネージ コードの sizeof() と同じ長さを返すことを確認することです。次に、ネイティブ コードをデバッグするときに、渡された引数が正しく表示されることを確認します。次に、ネイティブ コードでのポインターの使用法をトリプル チェックし、それらがコピーされていないことを確認します。

于 2011-04-03T15:04:49.327 に答える
0

これを試してみてください:

[DllImport("My.dll", EntryPoint = "_MyMethod@12")]
int MyMethod (HOLO_INFO pInfo, IntPtr pBuffer, IntPtr pTracksWritten);

public class HOLO_INFO
{
    public int    lHoloType;
    public int    lStatus;
    public IntPtr lThreadHandle;
    public int    lErrorCode;
    public int    lDriveIndex;
    public int    lHeight;
    public short  iFormat;
    public int    iStartingTrack;
    public int    lWrite;
    public int    lSkip;
    public bool   bSkipZero;
    public bool   bInvert;
    public int    lMaxConsecutiveErrors;
    public int    lMaxTotalErrors;
    public int    lMostConsecutiveErrors; 
    public int    lTotalErrors;
    public IntPtr pBuffer;
    public IntPtr pTracksWritten;
    public int    bUpsideDown;
}

それらがどのように割り当てられているかによって、Marshal.Copyto accessHOLO_INFO.pBufferおよびMarshal.PtrToStructureto accessを使用する必要がある場合がありますHOLO_INFO.pTracksWritten(またはMarshal.Copy、配列と特異値へのポインターの場合)。

于 2011-04-03T15:11:12.157 に答える
0

C++ で非常に C# の DLL を使用するを参照してください。

「単純な」トリック [この回答]( C++ で非常に C# DLL を使用する回答) を実行するか、私の回答に従って本格的な埋め込みを確認することができます。

于 2011-04-03T14:58:02.870 に答える