簡體   English   中英

如何將結構從C#傳遞到C ++ DLL?

[英]How to pass struct from C# to C++ DLL?

好的,我的激光設備控制器的一系列問題還在繼續...我想從我的C#代碼中調用DLL中的以下C ++函數:

extern "C" _declspec(dllimport) int SendFrame(DWORD deviceIndex, byte* pData, DWORD numOfPoints, DWORD scanrate);

指針pData指向在C ++頭文件中定義的激光點數組,如下所示:

#pragma pack (1)
struct LaserPoint {
    WORD x;
    WORD y;
    byte colors[6];
};

在C#端,我定義了函數import,如下所示:

[DllImport("..\\..\\dll\\StclDevices.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int SendFrame(UInt32 deviceIndex, ref byte[] pData, UInt32 numOfPoints, UInt32 scanrate);

...以及類似的LaserPoint結構:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct LaserPoint {
    public UInt16 x;
    public UInt16 y;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public byte[] colors;
}

然后我像這樣調用SendFrame函數:

LaserPoint point = new LaserPoint();
point.x = 16384;
point.y = 32768;
point.colors = new byte[] {255, 0, 0, 0, 0, 0};

byte[] arr = point2array(points);
SendFrame(0, ref arr, 1, 30000);

這是我將LaserPoint結構實例轉換為字節數組的功能:

private static byte[] point2array(object obj) {
    int len = Marshal.SizeOf(obj);
    byte[] arr = new byte[len];
    IntPtr ptr = Marshal.AllocHGlobal(len);
    Marshal.StructureToPtr(obj, ptr, true);
    Marshal.Copy(ptr, arr, 0, len);
    Marshal.FreeHGlobal(ptr);
    return arr;
}

但是我的激光設備沒有收到正確的輸入,因為激光的行為非常奇怪。 在C ++項目中使用相同的代碼可以正常工作。 因此,該C#互操作性代碼存在該錯誤。

有任何想法嗎?

數組已經是引用類型,因此ref byte[]是一個類似於byte**的雙重間接尋址—丟失了ref

如果僅打算在此處使用LaserPoint結構,則可以將函數定義為

[DllImport("..\\..\\dll\\StclDevices.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int SendFrame(UInt32 deviceIndex, LaserPoint[] pData, UInt32 numOfPoints, UInt32 scanrate);

並擺脫復制,讓運行時為您完成。

否則,如ildjarn所說,擺脫ref應該可以工作,因為字節數組已經是引用(指針)類型。

有關如何執行此操作的示例, PInvoke Wiki具有大多數Windows API的結構和簽名,因此盡管您的調用不存在,但仍有許多類似的示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM