1

プログラムで *.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 は間違った「ステータス コード」を返し、これは「無効なパラメータ」に変換されます。

どんな助けでも感謝します....

4

1 に答える 1

2

それを見つけた:

ソフトウェア開発者のドキュメントを決して信用しないでください: 実際にはパラメータがありませんでした (ドキュメントでは宣言されていませんが、sdk-package の別のサブディレクトリにある追加のヘッダー定義ファイルで宣言されています...)

したがって、実際には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 に感謝します...

于 2013-06-15T08:15:54.730 に答える