P /在结构中调用定义长度的C char *数组[重复]

Posted

技术标签:

【中文标题】P /在结构中调用定义长度的C char *数组[重复]【英文标题】:P/Invoking a defined-length C char* array in a struct [duplicate] 【发布时间】:2013-06-06 15:01:13 【问题描述】:

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

我一直在用结构做一些 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# 访问每个字符串的方式 P/Invoke 这个?制作单独返回每个函数的 C++ 函数不是一种选择。

【问题讨论】:

见***.com/questions/1985067/… 该问题仅提供了有关如何处理 C 中的实际字符串(即 char 数组)的答案,而不提供有关如何 P/Invoke 指向 C 字符串的指针数组的答案。跨度> 哎呀...没有注意到这一点。请参阅下面的答案。 【参考方案1】:

假设函数类似于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;
;

【讨论】:

谢谢,这对我们很有帮助。

以上是关于P /在结构中调用定义长度的C char *数组[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在c++中实现,如何创建一个char的数组

C语言遍历结构体数组

C语言-字符串相加考虑进位

C语言中,对于不知道长度的数组怎样输入。。。

c 复习

c 复习