如何在不指定缓冲区大小的情况下将C ++数组封送到C#?

时间:2015-07-10 13:44:24

标签: c# c++ arrays marshalling

我有C ++函数,它为C#方法提供了一个数组。我不知道我会有多少元素作为回报。我想要的是将一个数组(不指定元素计数)传递给C ++函数并将其重新填充。

到目前为止我的尝试:

C ++代码

unsigned int lib_infos(
    const char *code,
    char **err,
    int err_len,
    char **linkinfo,
    unsigned int* linksCount);

C#代码

[DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern uint lib_infos(
    [MarshalAs(UnmanagedType.LPStr)] string code,
    [MarshalAs(UnmanagedType.LPStr)] StringBuilder err,
    int err_len,
    [MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)] string[] linkInfo,
    out uint linksCount);

3 个答案:

答案 0 :(得分:0)

如果我正确理解了您的问题,那么您需要在不提供初始化缓冲区的情况下传递数组。如果是这样的话,我非常怀疑这可以实现,因为.NET中的数组是不可变的。

我目前无法访问Windows计算机,但我认为您必须执行此类操作(请注意不安全的关键字):

[DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
private unsafe static extern uint lib_infos(
    byte * code,
    [MarshalAs(UnmanagedType.LPStr)] StringBuilder err,
    int err_len,
    [MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)] string[] linkInfo,
    out uint linksCount);

当然,除非你在编译时添加/ unsafe(或类似的)标志,否则不会编译。

如果我是对的,我只能对你说:" ve con dios"。

说了这么多,你仍然需要在非托管层中分配内存然后 - 为了最终用户 - 包装P / Invoke调用以创建一个实际的string来返回

答案 1 :(得分:0)

这是不可能的。 C ++代码不能神奇地知道数组的大小 - 或者神奇地扩展你的数组以匹配。

必须有一个数组大小的通信协议 - 要么告诉它数组的大小,要么有效地要求N个项目,要么它告诉你有N个项目然后你提供一个这样大小的数组。 / p>

如果无法确定数据的大小,则无法来回传递数组。

答案 2 :(得分:0)

在末尾添加一个标记值。然后读取值,直到哨兵值,然后创建大小合适的c#数组。