2016-09-28 46 views
-1

我想用C++函數的代碼到.NET代碼我不能使用pinvke

MYDLL_API BOOL GetFolderSize(LPCTSTR lpszStartFolder, 
       BOOL bRecurse, 
       BOOL bQuickSize, 
       PLARGE_INTEGER lpFolderSize, 
       LPDWORD lpFolderCount /*= NULL*/, 
       LPDWORD lpFileCount /*= NULL*/); 

,所以我創建DLL導出代碼 然後在C#代碼中使用的PInvoke導入C++ DLL函數,C#

[StructLayout(LayoutKind.Explicit, Size = 8)] 
    struct LARGE_INTEGER 
    { 
     [FieldOffset(0)] 
     public Int64 QuadPart; 
     [FieldOffset(0)] 
     public UInt32 LowPart; 
     [FieldOffset(4)] 
     public Int32 HighPart; 
    } 

    [DllImport("mydll.dll")] 
    extern static bool GetFolderSize(string lpszStartFolder, 
           bool bRecurse, 
           bool bQuickSize, 
           out LARGE_INTEGER lpFolderSize, 
           out UInt32 lpFolderCount, 
           out UInt32 lpFileCount); 

這是什麼錯?

但是當我打電話它給我運行時異常 調用PInvoke函數'dublication!dublication.Form1 :: GetFolderSize'已經不平衡堆棧。這很可能是因爲託管的PInvoke簽名與非託管目標籤名不匹配。檢查的PInvoke簽名的調用約定和參數相匹配的非託管的目標籤名

+0

PLARGE_INTEGER和LPDWORD應該是'IntPtr',不是嗎? –

+0

我嘗試並重試這種方法,但它沒有工作,並且拋出了相同的異常 –

+1

@EdPlunkett「out」將已經添加指針。 –

回答

0

兩個問題我看到:

  • 調用約定:P/Invoke的默認調用約定是WINAPI。根據MYDLL_API的不同,您可能需要執行類似的操作[[DllImport("mydll.dll", CallingConvention = CallingConvention.Stdcall)]]

  • 字符串類型 - LPCTSTR不是默認的字符串轉換。

完整的聲明看起來像......

[DllImport("mydll.dll", CallingConvention = CallingConvention.Stdcall)] 
extern static int GetFolderSize(
    [MarshalAs(UnmanagedType.LPStr)] string lpszStartFolder, 
    int bRecurse, 
    int bQuickSize, 
    out long lpFolderSize, 
    out uint lpFolderCount, 
    out uint lpFileCount); 

如果您發佈MYDLL_API是什麼,我們將有更好的感覺。另外,如果你不反對將unsafe添加到所有內容中,我發現它使得指針/輸出參數/等更容易

+0

我會寫它 –

+0

我很抱歉,如果我不明白這個C++函數我該如何聲明它在c#通過PInvoke的__declspec(dllexport)的BOOL GetFolderSize(LPCTSTR lpszStartFolder, \t \t \t \t BOOL bRecurse, \t \t \t \t BOOL bQuickSize, \t \t \t \t PLARGE_INTEGER lpFolderSize, \t \t \t \t LPDWORD lpFolderCount/* = NULL * /, \t \t \t \t LPDWORD lpFileCount/* = NULL * /); –