如何从C#代码中调用非托管dll中的函数?

时间:2011-04-03 14:52:41

标签: c# c++ dllimport lpbyte

如何从C#中调用以下方法,这是在C ++ DLL中?如何在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,如果它是活动的                     0,如果成功完成                     3,如果由于错误而停止。 如果方法处于运行状态(Active-1)。它会修改 pInfo pTracksWritten 以更新状态信息。

3 个答案:

答案 0 :(得分:3)

很多问题:

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

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

答案 1 :(得分:0)

请参阅Using a Very C# DLL in C++

你可以做一个'简单'的技巧[这个回答](回答Using a Very C# DLL in C++),或者你可以按照my answer

查看全面嵌入

答案 2 :(得分: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如果是数组与指向奇异值的指针。)

相关问题