2013-06-12 54 views
1

我試圖訪問尼康圖像SDK(有興趣的人蔘見:1)來實現對程序中* .nef文件的訪問。我堅持從DLL的返回代碼應該被解釋爲「無效的參數」,並且我正在用盡想法。PInvoke Nikon C++ DLL函數來自c#

是的我知道這個機會,有人正在使用這個DLL是稀疏的,但我寧願尋找「寫作」/「思考」的錯誤...我仍然在學習(如此藉口任何錯誤使用條款等),也因此這是一個「稍長」的職位(在我身邊的一些「大聲思考」;-))

1.)該DLL有一個入口函數,標識符和結構作爲參數。標識符代表特定的命令(如打開,關閉等)。該結構用於與相機進行數據交換。

2)我有共同的一切和工作(因爲,我得到一個「返回代碼」),但我想不通的返回碼的原因(也許有些數據類型是不兼容的?)

因此,首先在 「C++」 - 部分:

C++函數定義:

extern "C" unsigned long __declspec(dllexport) WINAPI Nkfl_Entry(unsigned long ulCommand, void* pParam); 

這是STDCALL的,所以我需要擔心任何進一步的選項dllimport的,因爲usigned長(C++)對應以uint(c#)我得到兩個提示一個「出」和一個「在」...

C++結構確定指標:

typedef struct tagNkflLibraryParam 
{ 
    unsigned long ulSize;   // Size of structure 
    unsigned long ulVersion;  // Version 
    unsigned long ulVMMemorySize;  // Size of vertual memory 
    NkflPtr* pNkflPtr;     // Pointer of StratoObject 
    unsigned char VMFileInfo[ MAX_PATH ]; // Swap file info 
} NkflLibraryParam, *NkflLibraryPtr; 

所以確實需要3倍的uint,一個指針傳遞給一個 「StratoObject」((1)的醫生說 「的typedef void *的NkflPtr」,所以這是「只是「一個void *指針2.)doc說如果這是零它將由sdk填充),最後一個字節(因爲unsigned char(C++)對應於字節(c#))。

所以第一個問題:這是正確的嗎?

然後轉到 「編碼部分」:

C#結構確定指標:

namespace NikonStruct 
{ 
    [StructLayout(LayoutKind.Sequential)] 
    public struct NkflLibraryParam 
    { 
     public uint ulSize;   // size of the NkflLibraryParam structure 
     public uint ulVersion;  // version number of the interface specification 
     public uint ulVMMMemorySize; // upper limit of the physical memory that can be used 
     public IntPtr pNkflPtr;  // pointer to the StratoManager object 
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)] 
     public byte[] VMFileInfo;  // swap file information 
    } 
} 

現在這個應該符合我上面的defintions ...

C#程序類:

class Program 
{ 
    public enum eNkflCommand : int 
    { 
     kNkfl_Cmd_OpenLibrary = 1, 
     kNkfl_Cmd_CloseLibrary = 2, 
    }; 

    [DllImport("NkImgSDK.dll", EntryPoint = "Nkfl_Entry")] 
    public static extern uint kNkfl_Cmd_OpenLibrary(eNkflCommand ulCommand, ref NikonStruct.NkflLibraryParam data); 

    [DllImport("NkImgSDK.dll", EntryPoint = "Nkfl_Entry")] 
    public static extern uint kNkfl_Cmd_CloseLibrary(eNkflCommand ulCommand, IntPtr close); 

    static void Main(string[] args) 
    { 
     try 
     { 
      // specify return value of entry function 
      uint result1, result2; 

      /// call the kNkfl_Cmd_OpenLibrary Function 
      // generate data structure, which is used to communicate with kNkfl_Cmd_OpenLibrary function 
      NikonStruct.NkflLibraryParam _NkflLibraryParam = new NikonStruct.NkflLibraryParam(); 
      // fill the fields of _NkflLibraryParam structure for kNkfl_Cmd_OpenLibrary function 
      _NkflLibraryParam.ulVersion = 16777216; 
      _NkflLibraryParam.ulSize = ((uint)Marshal.SizeOf(_NkflLibraryParam)); ; 
      // call the entry function with parameters for kNkfl_Cmd_OpenLibrary 
      result1 = kNkfl_Cmd_OpenLibrary(eNkflCommand.kNkfl_Cmd_OpenLibrary, ref _NkflLibraryParam); 

      Console.WriteLine(result1); 

      /// call the kNkfl_Cmd_CloseLibrary Function 
      result2 = kNkfl_Cmd_CloseLibrary(eNkflCommand.kNkfl_Cmd_CloseLibrary, IntPtr.Zero); 

      Console.WriteLine(result2); 
     } 
     catch 
     { 
      string errorMsg = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message; 
      throw new ArgumentException(errorMsg); 
     } 
    } 
} 

所以沒什麼具體的:

  • eNkflCommand是從DOC
  • 結構通過引用如此REF傳遞...
  • 「關閉」 功能預計 「空指針」(根據DOC)
  • ulVersion是爲0x01000000(根據到DOC)
  • 所有其他結構值不是默認設置(並且是零,如果我理解正確的CLR DOC)

編譯和運行已經提到,但RESULT1返回錯誤「狀態,合作de「,如前所述,它轉化爲」無效參數「。

任何幫助表示讚賞....

+0

我不知道你是否在你的文章中提到它,但你爲什麼只在你的結構中設置ulVersion和ulSize?其他參數不是必需的嗎? – jszigeti

+0

@jszigeti:(...)所有其他結構值沒有設置(如果我正確理解clr文件,默認爲零)(...) :-) – Resu

+0

在黑暗中的另一個鏡頭:你能在C++中測試此代碼以確認SDK實際可用? (更重要的是,它的工作方式,你認爲它的作用) – jszigeti

回答

1

發現:

從不相信一個軟件開發的文檔:實際上有一個缺少參數(在文檔中,但額外的頭定義文件未聲明這是在SDK包的另一個子目錄...)

所以實際上在C#中的結構確定指標應該是:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
public struct struktur 
{ 
    public uint ulSize;   // size of the NkflLibraryParam structure 
    public uint ulVersion;  // version number of the interface specification 
    public uint ulVMMMemorySize; // upper limit of the physical memory that can be used 
    public IntPtr pNkflPtr;  // pointer to the StratoManager object 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)] 
    public byte[] VMFileInfo;  // swap file information 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)] 
    public byte[] DefProfPath; // <- this one is not included in the doc of NIKON (I still don't now what this should hold but it works if it's empty...) 
} 

感謝jszigeti和DavidHeffernan試圖...

+0

Resu。我也與尼康SDK一起工作。我會對與您合作的經驗感興趣,因爲我認爲與之合作的人數非常有限。如果您有時間討論一些想法以及您對圖書館所做的工作,那麼請隨時給我發一封電子郵件,郵件地址爲sks-innovations.net –

+0

我在C++控制檯應用程序中遇到了一個問題並嘗試你的應用程序和我遇到同樣的問題。加載庫上的錯誤代碼爲8。 (目標機器是Azure上的Windows Server 2012 R2)。它都可以在我自己的本地Windows Server 2012上運行。 –