我試圖訪問尼康圖像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「,如前所述,它轉化爲」無效參數「。
任何幫助表示讚賞....
我不知道你是否在你的文章中提到它,但你爲什麼只在你的結構中設置ulVersion和ulSize?其他參數不是必需的嗎? – jszigeti
@jszigeti:(...)所有其他結構值沒有設置(如果我正確理解clr文件,默認爲零)(...) :-) –
Resu
在黑暗中的另一個鏡頭:你能在C++中測試此代碼以確認SDK實際可用? (更重要的是,它的工作方式,你認爲它的作用) – jszigeti