我正在尝试访问尼康图像SDK(对于那些感兴趣的人:1)来实现对程序中* .nef文件的访问 . 我迟迟没想到了 .
是的我知道有一个机会,有人正在使用这个dll是稀疏的,但我宁愿寻找“写作”/“思考”错误......我还在学习(这是任何错误使用的术语等的借口等等 . ..)也因为这个原因这是一个“更长”的帖子(一些“大声思考”在我身边;-))
1.)dll有一个入口函数,您可以将标识符和结构作为参数传递 . 标识符代表特定命令(如打开,关闭等) . 该结构用于与相机进行数据交换 .
2.)我确实把所有东西放在一起工作(因为,我得到了一个“返回代码”)但是我无法弄清楚返回代码的原因(也许某些数据类型是不兼容的?)
首先是“C”部分:
c函数定义:
extern "C" unsigned long __declspec(dllexport) WINAPI Nkfl_Entry(unsigned long ulCommand, void* pParam );
这是stdcall,所以我确实需要担心dllimport的任何其他选项,因为usigned long(c)对应于uint(c#)我得到两个uint一个“out”和一个“in”......
c struct defintion:
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次uints,一个指向“StratoObject”的指针((1.)文档说“typedef void * NkflPtr”所以这只是“只是”一个void *指针2.)文档说如果这是它将由sdk填充,最后一个字节(因为unsigned char(c)对应于byte(c#)) .
所以第一个问题:这是正确的吗?
然后转到“编码部分”:
c#struct defintion:
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
}
}
现在这应该符合我上面的定义......
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 ...
-
"close"函数需要"null pointer"(根据doc)
-
ulVersion是0x01000000(根据doc)
-
未设置所有其他结构值(如果我正确理解了clr文档,则默认为零)
如前所述编译和运行但是result1返回错误的“状态代码”,它转换为已经提到的“无效参数” .
任何帮助赞赏....
1 回答
找到了:
永远不要相信软件开发人员的文档:实际上有一个缺少的参数(未在文档中声明BUT在另一个头文件定义文件中,该文件位于sdk-package的另一个子目录中...)
实际上c#中的结构定义应该是:
感谢jszigeti和DavidHeffernan尝试...