0

我已经找了一段时间,但没有找到可以提供答案的文章,所以希望它不是重复的。

我一直在用一个结构做一些 P/Invoking,这很好,一切都很好,但后来我看到了:

char* infoString[SIDTUNE_MAX_CREDIT_STRINGS];

其中 SIDTUNE_MAX_CREDIT_STRINGS 定义为 10。

因此内联所有内容,结构成员定义为:

char* infoString[10]

现在,这与我尝试解决的其他问题略有不同。

char* 数组包含指向其他 C 字符串的指针。

在这种特定情况下,仅使用了 3 个索引,而其余的则被保留。指标如下:

  • infoString[0] = 歌曲名称

  • infoString[1] = 艺术家姓名

  • infoString[2] = 版权/出版商。

如何以我可以从 C# 访问每个字符串的方式进行 IP/Invoke?制作单独返回每个函数的 C++ 函数不是一种选择。

4

1 回答 1

0

假设函数类似于GetSongInfo(int songID, LPInfostring songinfo),您可以将 定义struct为具有 的数组IntPtr。但是,您必须注意内存泄漏,因为调用函数可能希望您释放为返回的字符串分配的内存。

目标.h:

typedef struct SongInfo
{
    char* infoString[10];
} *LPSongInfo;

extern "C" __declspec(dllexport) int GetSongInfo(int songID, LPSongInfo info);

目标.c:

extern "C" __declspec(dllexport) int GetSongInfo(int songID, LPSongInfo demo)
{
    demo->infoString[0] = "Hello world";
    demo->infoString[1] = "Hello 1";
    demo->infoString[2] = "Hello 2";

    return TRUE;
}

P/调用签名:

[DllImport("PInvokeDll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int GetSongInfo(int songID, out SongInfo ts);

[StructLayout(LayoutKind.Sequential)]
struct SongInfo
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
    public IntPtr[] infoString;
};

使用示例:

SongInfo siStruct;
var num2 = GetSongInfo(101, out siStruct);

// copy the results to managed memory
var results = new string[10];
for (int i = 0; i < 10; i++)
{
    if (siStruct.infoString[i] != IntPtr.Zero)
    {
        // if these were Unicode strings, this would change to PtrToSTringUni
        results[i] = Marshal.PtrToStringAnsi(siStruct.infoString[i]);
    }
}

// results now holds the .Net strings
// if there is an expectation of the caller to free the struct 
// strings, that should happen now

作为不分配内存的函数的替代方案,您可以使用如下结构来自动编组字符串。但是,它将无条件释放非托管内存,这可能是可取的,也可能不是可取的。

[StructLayout(LayoutKind.Sequential)]
struct SongInfo2
{
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.LPStr, SizeConst = 10)]
    public string[] infoString;
};
于 2013-06-06T17:45:54.107 回答