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

因为,它返回 1,如果它是 Active 0,如果它成功完成 3,如果它因为错误而停止。如果方法处于运行状态(Active-1)。它修改pInfopTracksWritten以更新状态信息。

4

3 回答 3

3

很多问题:

  • LONG 应该在 C# 中声明为 int
  • HANDLE 是 IntPtr。
  • pTracksWritten 丢失。您可能需要制作它,pBuffer,一个 IntPtr 并使用 Marshal.AllocHGlobal 为它们分配内存,这取决于。
  • 您需要 [DllImport] 声明中的 CallingConvention 才能使用 Cdecl。

如果您无法调试非托管代码,那么让它工作的可能性并不大。一项基本的健全性测试是确保 Marshal.SizeOf() 在非托管代码中返回与 sizeof() 相同的长度。接下来验证在调试本机代码时传递的参数看起来不错。接下来三重检查本机代码中的指针使用情况,并验证它们没有被复制。

于 2011-04-03T15:04:49.327 回答
0

请参阅在 C++ 中使用非常 C# 的 DLL

您可以做一个“简单”的技巧 [this answer](answer Using a Very C# DLL in C++ ),或者您可以按照我的回答查看完整的嵌入

于 2011-04-03T14:58:02.870 回答
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.Copy来访问HOLO_INFO.pBufferMarshal.PtrToStructure访问HOLO_INFO.pTracksWritten(或者Marshal.Copy如果它是数组与指向奇异值的指针)。

于 2011-04-03T15:11:12.157 回答