2011-07-05 61 views
1

我無法從外部DLL例程接收數據。該DLL將從微控制器芯片讀取數據。這在Delphi中正常工作,我試圖讓它在C#中工作。MarshalAs C in question#

阿黴素:起始地址 長度:正被讀取的數據的總長度

該函數返回一個TDATA陣列,其中索引爲0的項包含起始 地址和索引1的項目包含的長度收到的數據。以下 項目(索引2和更高)包含收到的數據。如果接收操作失敗,則陣列中返回的 長度值設置爲零

[DllImport("dsio.dll", CallingConvention = CallingConvention.StdCall)] 
    [return: MarshalAs(UnmanagedType.LPArray)] 
    public static extern byte[] Receive(int Adr, int Len); 

    private void BtnReceive_Click(object sender, EventArgs e) 
    { 
     byte[] Data = new byte[256]; 
     int Adr = 0x05; 
     int Len = 8; 

     Data = Receive(Adr, Len); 
     txtBox2.Text = Data; 
    } 
+0

很不清楚這個函數返回什麼。除此之外,它不是byte []。 –

+0

你有沒有試過不使用MarshalAs?你知道如果DLL正在返回一個C風格的數組或SafeArray? –

+0

以任何語言顯示調用此函數的C函數原型和代碼片段(更好的C)。 –

回答

1

首先,它是不必要的實例new byte[256]因爲要設置Data到的Receive()返回結果。

您應該嘗試刪除[return: MarshalAs]屬性以查看默認編組是否工作。

如果它不工作,this documentation表明SizeConstSizeParamIndex也應在MarshalAs屬性聲明中使用UnmanagedType.LPArray時設置。我不知道你是否需要使用這些參數中的一個或兩個(閱讀鏈接文檔和實驗)。 SizeParamIndex,如果需要,將會是1,因爲第二個參數是長度。

[return: MarshalAs(UnmanagedType.LPArray, SizeConst = 256, SizeParamIndex = 1)] 

附錄:既然你聲明TData作爲一種類型,這給了我一個想法,在C#中使用struct也可以工作,它有助於隔離前2個字節,如果它:

[StructLayout(LayoutKind.Sequential)] 
public struct TData { 
    public byte StartAddress = 0; 
    public byte Length = 0; 
    public byte[] Data = new byte[ 254 ]; 
} 

如果您嘗試使用此功能,我很肯定您會刪除return: MarshalAs,並且默認封送處理應該可以正常工作。

+0

感謝您的幫助,我刪除了'new byte [256]'和'[return:MarshalAs]'屬性,在這一行的錯誤沒有任何變化,'Data = Receive(Adr,Len)'「MarshalDirectiveException未處理」 「無法封送'返回值':無效的託管/非託管類型組合」Adr是一個內存指針,Len是接收到的數據的長度。 – Steve

+0

對不起,我忽略了'LPArray'的提及。什麼意思是如果你確實需要使用LPArray,請嘗試指定'MarshalAs'屬性的'SizeConst'和'SizeParamIndex'。 –

+0

Joel,你會有一個LPArry,SizeConst,SizeParamIndex結構的例子嗎? – Steve