C# (システム、ゲーム、曲、著作権など) からこの構造体の const char* メンバーにアクセスできるように、これを P/invoke しようとしています。
これは、C++ ヘッダーで定義されている構造体です: gme.hの 79 行目から
struct gme_info_t
{
/* times in milliseconds; -1 if unknown */
int length; /* total length, if file specifies it */
int intro_length; /* length of song up to looping section */
int loop_length; /* length of looping section */
/* Length if available, otherwise intro_length+loop_length*2 if available,
otherwise a default of 150000 (2.5 minutes). */
int play_length;
int i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15; /* reserved */
/* empty string ("") if not available */
const char* system;
const char* game;
const char* song;
const char* author;
const char* copyright;
const char* comment;
const char* dumper;
const char *s7,*s8,*s9,*s10,*s11,*s12,*s13,*s14,*s15; /* reserved */
};
私の C# コードでは、この構造体を次のようにモデル化しました。
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct gme_info_t
{
public int length;
public int introLength;
public int loopLength;
public int playLength;
public int i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15;
public string system;
public string game;
public string song;
public string author;
public string copyright;
public string comment;
public string dumper;
public string s7, s8, s9, s10, s11, s12, s13, s14, s15;
}
今、私が呼び出している関数は、次のような C++ プロトタイプを持つ P/Invoked の関数です。
gme_err_t gme_track_info( Music_Emu const* me, gme_info_t** out, int track )
はどこgme_err_t
ですかconst char*
(直接見たい場合は、gme.h の 74 行目を参照してください)
(定義についてはgme.cppの 252 行目を参照)
したがって、すべての typedef を含まない関数は次のようになります。
const char* gme_track_info( Music_Emu const* me, gme_info_t** out, int track )
この関数が機能する方法は、有効な Music_Emu と有効なトラックで呼び出されると、結果はパラメータ 'out' に割り当てられた音楽トラックに関する情報です。
返される const char* は、基本的にエラーが発生した場合のためのものであるため、主な焦点ではありません。「out」パラメータは.
C# でこの関数の P/Invoke を次のように定義しました。
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern string gme_track_info(IntPtr emuHandle, out gme_info_t trackInfo, int track);
現在、その構造体で著作権文字列を読み取ろうとする私のコードを次に示します。
static void Main()
{
// Initialize the MusicEmu reference first (this works fine).
IntPtr emuRef;
string initEmuRef = NativeMethods.gme_open_file("Adventure Island 4.nsf", out emuRef, 48000);
Console.WriteLine("Error Message (if any): " + initEmuRef);
// Now get the track info.
gme_info_t trackInfo;
NativeMethods.gme_track_info(emuRef, out trackInfo, 0);
Console.WriteLine("Copyright: " + trackInfo.copyright); // I get an empty string. When checked with a different NSF reader it prints "1994 Hudson Soft."
// Keep console window up.
Console.ReadLine();
}
どんな助けでも大歓迎です。これを機能させるために約4時間試しました。考えられる解決策について、StackOverflow (および一般的なネット) を隅々まで調べましたが、この種の質問に近いものは見つかりませんでした。他のほとんどの問題は、配列の構造体へのポインターへのポインターなどに関するものであり、この場合にはまったく役に立ちません。
その他の情報が必要な場合は、お問い合わせください。喜んで提供いたします。