プログラムで *.nef ファイルへのアクセスを実装するために、Nikon イメージ SDK にアクセスしようとしています (興味のある方は1を参照してください)。「無効なパラメーター」として解釈されるはずの dll からのリターン コードでスタックしており、アイデアが不足しています。
はい、私は誰かがこの dll を正確に使用している可能性を知っていますが、むしろ「書き込み」/「思考」エラーを探しています...私はまだ学んでいます (間違った使用用語などは言い訳. ..) また、この理由から、これは少し「長い」投稿です (私の側ではいくつかの「声に出して考える」;-) )
1.) dll には、識別子と構造体をパラメーターとして渡すエントリ関数があります。識別子は特定のコマンド (open、close など) を表します。構造体は、カメラとのデータ交換に使用されます。
2.) 私はすべてをまとめて動作させています (「リターン コード」を受け取っているため) が、リターン コードの理由がわかりません (データ型に互換性がない可能性がありますか?)
最初に「C++」の部分:
C++ 関数定義:
extern "C" unsigned long __declspec(dllexport) WINAPI Nkfl_Entry(unsigned long ulCommand, void* pParam );
これはstdcallなので、dllimportのその他のオプションについて心配する必要があります。
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;
したがって、「StratoObject」への1つのポインターである3回のuintを渡す必要があります((1。)ドキュメントには「typedef void * NkflPtr」と記載されているため、これは「単なる」void *ポインター2です。)ドキュメントは、これがゼロは SDK によって埋められます)、最後に 1 バイトです (unsigned char(c++) は byte(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
}
}
今、これは上記の私の定義に対応するはずです...
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 はドキュメントからのものです
- 構造体は参照渡しなので、ref...
- 「閉じる」関数は「ヌルポインター」を期待しています(ドキュメントによると)
- ulVersion は 0x01000000 です (ドキュメントによると)
- 他のすべての構造体値は設定されていません (clr ドキュメントを正しく理解していれば、デフォルトでゼロです)
既に述べたようにコンパイルして実行しますが、すでに述べたように、result1 は間違った「ステータス コード」を返し、これは「無効なパラメータ」に変換されます。
どんな助けでも感謝します....