-1

プロジェクトで P/Invoke を使用して C++ dll を使用する必要があります。構造体も含む関数を呼び出しています。これは AccessViolationException を生成します。

詳細は次のとおりです。以下は c++ 関数です。

Int BII_Read_Transaction_Log_Ex(int iOption, int iUpdateFlag, int *iMaxEntries, BII_Transaction_Log_Ex *log)

これが私のメソッド宣言です。

[DllImport(@"C:\Program Files (x86)\Bioscrypt\SecureSDK\DLL\BII_V1100.dll", EntryPoint = "BII_Read_Transaction_Log_Ex")]
public unsafe static extern int GetTransactionLogs(int option, int updateFlag, ref int maxEnteries, ref BII_Transaction_Log_Ex[] transactionLogs);

次の構造体が含まれます。

typedef struct
{
unsigned int id; // ID of the template whose action was recorded
unsigned char reserved_1;
unsigned char index; // Index of the template whose action was recorded
unsigned short year; // Years since 2002 action was recorded
unsigned char month; // Months since January action was recorded (0-11) unsigned char
unsigned char day; // Day of month action was recorded (1-31)
unsigned char hour; // Hour (0-23), Minute and Second (0-59) – Time of action
unsigned char min;
unsigned char sec;
unsigned char trans_code; // Trans_code, Data1, Data2, Data3 – See table below
unsigned char flag_port; //Bit 5. Bit 6 Bit 7 unused Bit 0-4: port (0 – host, 1 – aux, 3–Wiegand, 5 – GPI0, 6 – GPI1, 8 – Search)
unsigned char trans_log_data_1;
unsigned char trans_log_data_2;
unsigned char trans_log_data_3;
unsigned char reserved_2;
unsigned char status; //0 if action failed, 1 if action succeeded
char name[16]; // Name field of Template for which log is stored
unsigned short duration; // Enroll / Verify duration in milliseconds
unsigned short template_size; // Size of template in bytes for which log is stored
signed short error_code; // Error code if enroll / verify failed
unsigned char sensor_type; // Sensor type connected to device
unsigned char unit_id; // Unit ID assigned to device, same as net ID (Get/Set command for net ID BII_GET_NETID / BII_SET_NETID)
unsigned char admin_level; // Admin level of template for which log is stored
unsigned char rsz_3; /* Reserved */
unsigned char rsz_4; /* Reserved */
unsigned char rsz_5; /* Reserved */
char ta_msg[16]; /*F1,F2,F3,F4 key message */
}BII_Transaction_Log_Ex;

C# でのこの構造体の実装は次のとおりです。

[StructLayout(LayoutKind.Sequential, Pack = 1)]
   public struct BII_Transaction_Log_Ex
   {
     public  UInt32 id; // ID of the template whose action was recorded
     public  Byte reserved_1;
     public  Byte index; // Index of the template whose action was recorded
     public  UInt16 year; // Years since 2002 action was recorded
     public  Byte month; // Months since January action was recorded (0-11) unsigned char
     public  Byte day; // Day of month action was recorded (1-31)
     public  Byte hour; // Hour (0-23), Minute and Second (0-59) – Time of action
     public  Byte min;
     public  Byte sec;
     public  Byte trans_code; // Trans_code, Data1, Data2, Data3 – See table below
     public  Byte flag_port; //Bit 5. Bit 6 Bit 7 unused Bit 0-4: port (0 – host, 1 – aux, 3– Wiegand, 5 – GPI0, 6 – GPI1, 8 – Search)
     public  Byte trans_log_data_1;
     public  Byte trans_log_data_2;
     public  Byte trans_log_data_3;
     public  Byte reserved_2;
     public  Byte status; //0 if action failed, 1 if action succeeded
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
     public  byte[] name; //char name[16]; // Name field of Template for which log is stored
     public  UInt16 duration; // Enroll / Verify duration in milliseconds
     public  UInt16 template_size; // Size of template in bytes for which log is stored
     public  SByte error_code; // Error code if enroll / verify failed
     public  Byte sensor_type; // Sensor type connected to device
     public  Byte unit_id; // Unit ID assigned to device, same as net ID (Get/Set command for net ID BII_GET_NETID / BII_SET_NETID)
     public  Byte admin_level; // Admin level of template for which log is stored
     public  Byte rsz_3; /* Reserved */
     public  Byte rsz_4; /* Reserved */
     public  Byte rsz_5; /* Reserved */
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
     public  byte[] ta_msg; /*F1,F2,F3,F4 key message */
   }

使用して関数を呼び出すと、AccessViolationException が生成され、次のメッセージが表示されます。

    int transactionsCount=-1;
    BII_Transaction_Log_Ex[] logs = new BII_Transaction_Log_Ex[1000];
    int result = GetTransactionLogs(0, 0, ref transactionsCount, ref logs);

関連する構造体をマーシェリングする際に間違いを犯していると思いますが、これまでのところ正確な問題を見つけることができません。どんな助けでも大歓迎です..

編集: C++ ソース コードがありません。

4

1 に答える 1

0

C++ 関数は次のように宣言されます。

int BII_Read_Transaction_Log_Ex(
    int iOption, 
    int iUpdateFlag, 
    int *iMaxEntries, 
    BII_Transaction_Log_Ex *log
);

最後のパラメーターは、参照によって渡される単一の構造体にすることができます。その場合、C# は次のようになります。

[DllImport(@"...", CallingConvention=CallingConvention.Cdecl,
    EntryPoint = "BII_Read_Transaction_Log_Ex")]
public static extern int GetTransactionLogs(
    int option, 
    int updateFlag, 
    ref int maxEntries, 
    ref BII_Transaction_Log_Ex transactionLogs
);

ここでは unsafe は必要ないので、削除しました。そして、C++ 関数が使用するcdecl.

ただし、複数形のtransactionLogs, とmaxEntriesパラメータを使用すると、C++ コードが配列を想定していると思われます。その場合、次のように記述します。

[DllImport(@"...", CallingConvention=CallingConvention.Cdecl,
    EntryPoint = "BII_Read_Transaction_Log_Ex")]
public static extern int GetTransactionLogs(
    int option, 
    int updateFlag, 
    ref int maxEntries, 
    [Out] BII_Transaction_Log_Ex[] transactionLogs
);

Pack=1また、構造体定義での使用についてはやや懐疑的です。何があなたをそうさせたのですか。削除する必要がある場合は、整列された構造体が必要Packです。C++ 構造体はパディングが追加されるスペースに予約済みメンバーを配置するため、問題ではないと思いますが、構造体が整列されていると宣言されていることを確認したいと思います。

于 2013-07-18T11:10:07.137 に答える