[英]PInvoke Nikon c++ DLL Function from c#
I'm trying to access the Nikon image SDK(for those interested see: 1 ) to implement access to *.nef file in a programm. 我正在尝试访问Nikon图像SDK(对于那些感兴趣的人,请参阅: 1 )以在程序中实现对* .nef文件的访问。 I'm stuck at a return code from the dll which should be interpreted as "invalid parameter" and I'm running out of ideas.
我被困在dll的返回码中,该返回码应解释为“无效参数”,并且我的想法已用尽。
Yes I know the chance, that somebody is exactly using this dll is sparse, but I'm rather looking for "writing"/"thinking" errors... I'm still learning (so excuse to any wrong used terms, etc...) and also for this reason this is a little "longer" post (some "aloud thinking" on my side ;-) ) 是的,我知道有机会,确实有人在使用此dll,但我只是在寻找“写” /“思考”错误...我还在学习(因此,请原谅任何错误使用的术语,等等。) ..)也是出于这个原因,这是一个“较长”的帖子(我这边有些“沉思” ;-))
1.) the dll has an entry function where you pass a identifier and a struct as parameter. 1.)dll具有进入功能,您可以在其中传递标识符和结构作为参数。 The identifier stands for a specific command (like open,close,etc....).
标识符代表特定的命令(如打开,关闭等)。 The struct is used for data exchange with the camera.
该结构用于与相机进行数据交换。
2.) I do have everything together and working (since, I'm getting a "return code") but I can't figure out the reason for the return code (maybe some datatype is incompatible?) 2.)我确实将所有东西都放在一起工作(因为,我得到了一个“返回码”),但是我无法弄清楚返回码的原因(也许某些数据类型不兼容?)
So first the "C++"-part: 因此,首先是“ C ++”部分:
c++ function definition: C ++函数定义:
extern "C" unsigned long __declspec(dllexport) WINAPI Nkfl_Entry(unsigned long ulCommand, void* pParam );
this is stdcall, so I do need to worry about any further options to dllimport, since usigned long(c++) corresponds to uint(c#) i get two uints one "out" and one "in"... 这是stdcall,所以我确实需要担心dllimport的任何其他选项,因为usigned long(c ++)对应于uint(c#),我得到两个uint,一个为“ out”,一个为“ in” ...
c++ struct defintion: 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;
so I do need to pass 3 times uints, one pointer to an "StratoObject" ((1.) the doc says "typedef void* NkflPtr" so this is "just" a void* pointer 2.) the doc says if this is zero it will be filled up by the sdk) and finally one byte (since unsigned char(c++) corresponds to byte(c#)). 所以我确实需要传递3次uint,一个指向“ StratoObject”的指针((1。)文档说“ typedef void * NkflPtr”,所以这“只是” void *指针2。)文档说如果是零将由sdk填充),最后是一个字节(因为无符号char(c ++)对应于byte(c#))。
So first question: Is this correct? 所以第一个问题:这是正确的吗?
Then going to the "coding-part": 然后转到“编码部分”:
c# struct defintion: 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
}
}
now this should correspond to my defintions above... 现在这应该符合我上面的定义...
c# Program class: 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);
}
}
}
So nothing specific here: 因此,这里没有具体内容:
Compiles and runs as already mentioned but result1 returns wrong "status-code" which translates to "invalid param" as already mentioned. 如前所述编译并运行,但result1返回错误的“状态代码”,如前所述,该状态代码转换为“无效参数”。
Any help appreciated.... 任何帮助表示赞赏。
FOUND IT: 找到了:
never trust a documentation of a software developer: there was actually a missing parameter (not declared in the documentation BUT in an additional header definition file which was in another sub-directory of the sdk-package...) 永远不要信任软件开发人员的文档:实际上缺少一个参数(在文档BUT中未在sdk-package的另一个子目录中的其他头文件定义文件中声明...)
so actually the struct defintion in the c# should be: 所以实际上C#中的struct定义应该是:
[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...)
}
Thanks to jszigeti and DavidHeffernan for trying... 感谢jszigeti和DavidHeffernan尝试...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.