2013-06-12 59 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上运行。 –