|
分類:[C#]
はじめまして。Bakutikuと申します。
C#をはじめて間もない身ですが、引数が複雑なC++のDllの呼び出しが出来ず困っています。
C++で作成されたネイティブのDLL関数をC#で呼び出そうとしています。
DLL側(C++)の引数は以下のように定義されています。
// メソッド
char* piyo(char* fuga,TS_Hoge pS_Hoge)
// 構造体 TS_Hoge
typedef struct TS_Hoge {
int count;
char** path;
pS_Data Data;
} S_Hoge, *pS_Hoge;
// 構造体 TS_Data
typedef struct TS_Data {
char id[11];
} S_Data, *pS_Data;
●この処理を、C#からは以下のように宣言して呼び出しています。
◆ 宣言
[DllImport("test.dll")]
private static extern string piyo(StringBuilder fuga, ref TS_Hoge pS_Hoge);
// TS_Hogeの定義
[StructLayout(LayoutKind.Sequential)]
public struct TS_Hoge
{
public int count;
public unsafe char** path;
public TS_Data Data;
}
// TS_Dataの定義
[StructLayout(LayoutKind.Sequential)]
public struct TS_Data
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string id;
}
◆ 処理
TS_Hoge tS_Hoge;
TS_Data tS_Data;
tS_Data.id = "test";
tS_Hoge.count = 1;
tS_Hoge.Data = tS_Data;
// ポインタのポインタ作成
string s = @"C:\Hoge\piyo.txt";
char[] a = s.ToCharArray(); // ポインタのポインタ作成用のChar配列
char*[] b = new char*[256];
//ポインタのポインタ作成
fixed (char** fp = b) // 処理中のマネージ変数を固定する
{
for(int i = 0 ; i<256; i++)
{
fixed (char* pa = &a[i])
{
fp[i] = pa;
}
}
tS_Hoge.path = fp; // ポインタのポインタを設定
}
string ret;
StringBuilder fuga = new StringBuilder(11);
fuga.Append("12345");
ret = piyo(fuga,ref tS_Hoge);
◆事象
上記のように記述したうえで呼び出しを行うと、C++のDLL内部の以下のような入力チェック処理で引っかかり、エラーのリターンコードが返されてしまいます。特に例外は発生しません。
/*--------------------------*/
/* 入力パラメータのチェック */
/*--------------------------*/
if ( fuga == NULL || pS_Hoge == NULL ){
memcpy( rtn, "inputError", sizeof(rtn) );
return &rtn[0] ;
} else if( pS_Hoge->count == 0
|| pS_Hoge->path == NULL
|| pS_Hoge->tS_Data == NULL ) {
memcpy( rtn, "inputError", sizeof(rtn) );
return( &rtn[0] );
}
自分としてはポインタのポインタの受け渡しが悪いのかなと思っていますが、
構造体の中に構造体を設定して呼び出しを行うところも自信がなく、
どれが正しいのか判断が付かない状態になってしまいました。
非常に長くなってしまいましたが、少しでもヒントをいただけるとありがたいです。
以上、よろしくお願いします。
|