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 *数组[重复]的主要内容,如果未能解决你的问题,请参考以下文章