2010-03-22 49 views
2

試圖從Oracle的Outside In API中互操作功能。 具備以下功能:問題獲得C#P的正確參數/調用C++ DLL的調用

SCCERR EXOpenExport {VTHDOC hDoc, VTDWORD dwOutputId, VTDWORD dwSpecType, 
VTLPVOID pSpec, VTDWORD dwFlags, VTSYSPARAM dwReserved, VTLPVOID pCallbackFunc, 
VTSYSPARAM dwCallbackData, VTLPHEXPORT phExport); 

從頭文件我的參數減少到:
的typedef VTSYSPARAM VTHDOC,VTLPHDOC *
的typedef DWORD_PTR VTSYSPARAM
的typedef unsigned long類型DWORD_PTR

typedef unsigned long VTDWORD 

typedef VTVOID* VTLPVOID 
#define VTVOID void 

typedef VTHDOC VTHEXPORT, *VTLPEXPORT 
These are for 32 bit windows 

展望通過頭文件,示例程序和我發現的文檔:
1. pSpec可能是poi中間到一個緩衝區或NULL,所以我把它設置爲一個IntPtr.Zero(文檔)。
2.該dwFlags和dwReserved根據文檔「必須由開發人員設置爲0」。
3.如果我不想處理回調,可以將pCallbackFunc設置爲NULL。
4.最後兩個是基於我使用[StructLayout(LayoutKind.Sequential)]編寫C#包裝器的結構。然後通過首先創建一個帶有Marshal.AllocHGlobal(Marshal.SizeOf(instance))的IntPtr來創建一個實例並生成參數,然後獲取作爲uint傳遞給dwCallbackData的地址值和一個用於phExport的IntPtr。

最後一個參數列表如下: 1. phDoc作爲IntPtr,之前被稱爲 的DAOpenDocument函數加載了一個地址。
2.如dwOutputId UINT設置爲1535代表FI_JPEGFIF
3. dwSpecType爲INT設定爲2,其表示IOTYPE_ANSIPATH
4. PSPEC作爲IntPtr.Zero其中輸出將被寫入
5.如dwFlags中UINT組爲0的指示
6.如dwReserved UINT設置爲0的指示
7.如pCallbackFunc的IntPtr設置爲NULL,我將處理結果
8. dwCallBackDate作爲UINT一個緩衝區的地址,一個結構
9。 phExport作爲IntPtr到另一個結構緩衝區

仍然從API中收到未定義的錯誤。這意味着該調用返回一個961,這在任何頭文件中都沒有定義。在過去,當我選擇的參數類型不正確時,我已經得到了這個結果。
我開始使用Interop Assistant,它有助於瞭解有多少參數類型可以被翻譯。但是,它受限於我能夠從頭文件中收集正確的本機類型。例如,前面函數中使用的hDoc參數被定義爲非文件名句柄,因此試圖使用Marshal創建句柄,然後使用IntPtr,最後它變成了一個int(實際上它是使用了&的phDoc這裏)。
那麼除了反覆試驗外,還有更科學的方法嗎?
吉姆

+0

你有沒有試過http://pinvoke.net? – 2010-04-05 15:26:51

+0

961是十六進制的3C1。這是在sccerr中定義的。h作爲「訪問違規」 – 2011-11-14 21:28:11

回答

0

您可以搜索http://pinvoke.net對現有的解決方案,或者你可以嘗試PInvoke Signature Toolkit。這些可能會提供一些幫助。

+0

有使用過ToolKit,但它仍然是一個猜謎遊戲 – 2010-04-13 15:50:28

+0

@Jim:對我來說沒有任何爭論。要正確簽署這些簽名可能非常困難。我經常訴諸於用C++/CLI編寫一些包裝,然後將這些包裝暴露給C#。 – 2010-04-13 17:00:59