开发者

How to call a function in an unmanaged dll from C# Code?

开发者 https://www.devze.com 2023-02-21 22:54 出处:网络
How can I call the following method from C#, which is in a C++ dll? How Can I recreatethe following structure in C#?

How can I call the following method from C#, which is in a C++ dll? How Can I recreate the following structure in C#?


Original

Method:

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

Structure: This method uses the following structure:

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;

I worked in C# like this

Method:

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

Structure:

This method uses the following structure:

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

I made a call to the method like this:

  do
  {
    result = MyMetho开发者_开发技巧d(ref pInfo,ptrBuf,pTracksWritten);
  } while (result ==1 );

Because, it returns 1, if it is Active 0, if it completed successfully 3, if it stopped because of error. if the method is in running state(Active-1). it modifies pInfo and pTracksWritten to update the status information.


Lots of issues:

  • LONG should be declared as int in C#
  • HANDLE is IntPtr.
  • pTracksWritten is missing. You probably need to make it, and pBuffer, an IntPtr and use Marshal.AllocHGlobal to allocate memory for them, depends.
  • You need the CallingConvention in the [DllImport] declaration to use Cdecl.

Odds of getting this to work are not great if you can't debug the unmanaged code. One basic sanity test is to make sure that Marshal.SizeOf() returns the same length as sizeof() in the unmanaged code. Next verify that passed arguments look good when debugging the native code. Next triple-check the pointer usage in the native code and verify that they are not getting copied.


See Using a Very C# DLL in C++

You can do a 'simple' trick [this answer](answer Using a Very C# DLL in C++) or you can have a look at fullblown embedding as per my answer


Give this a shot:

[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;
}

Depending on how they're allocated, you may need to use Marshal.Copy to access HOLO_INFO.pBuffer and Marshal.PtrToStructure to access HOLO_INFO.pTracksWritten (or Marshal.Copy if it's an array vs. a pointer to a singular value).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号