我正在尝试以这种方式调用它,我应该能够从C#(系统,游戏,歌曲,版权等)访问此结构的const char *成员。
这是结构,因为它在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;
}
现在,我正在调用的函数是我有P / Invoked的函数,它具有C ++原型,如下所示:
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(以及一般的网络)周围寻找可能的解决方案,但我还没有找到任何接近这类问题的方法。大多数其他问题都是关于指向数组结构的指针的指针,这对于这种情况根本不是很有帮助。
如果需要任何其他信息,请问,我很乐意提供。
答案 0 :(得分:0)
您的trackInfo
参数应为out IntPtr
。然后,您可以使用Marshal.PtrToStructure
方法将其编组为C#结构。
IntPtr trackInfoPtr;
NativeMethods.gme_track_info(emuRef, out trackInfoPtr);
gme_info_t trackInfo = (gme_info_t)Marshal.PtrToStructure(trackInfoPtr, typeof(gme_info_t));