我试图访问尼康图像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