首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >字符串数组作为从C到C的返回值?

字符串数组作为从C到C的返回值?
EN

Stack Overflow用户
提问于 2018-09-04 05:04:43
回答 1查看 0关注 0票数 0

如何将一个字符串数组(char**)从本机C函数返回到string[]C#中的托管类型?

这有效:

代码语言:javascript
复制
C:
char* get_text() {
    size_t length = ...;
    char *text = (char *)CoTaskMemAlloc((length + 1) * sizeof(char));
    // populate text...
    return text;
}

C#:
[DllImport(LibName, EntryPoint = "get_text", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.LPStr)]
private static extern string GetText();

但是,我无法开展工作:

代码语言:javascript
复制
C:
char** get_texts() {
    size_t count = ...;
    char **texts = (char **)CoTaskMemAloc(count * sizeof(char*));
    for (size_t i = 0; i < count; ++i) {
        size_t length = ...;
        texts[i] = (char *)CoTaskMemAlloc((length + 1) * sizeof(char));
        // populate texts[i]
    }
    return texts;
}

C#:
[DllImport(LibName, EntryPoint = "get_texts", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(???)]
private static extern string[] GetTexts();

我已经尝试将返回类型设置为marshal as LPArraySafeArraywith SafeArraySubType = VarEnum.VT_LPSTR,但我无法让它工作。使用LPArray似乎建议我应该传入数组大小的参数(以及子类型,这是LPStr),但我不知道调用时的大小。

怎么能实现这一目标?

EN

回答 1

Stack Overflow用户

发布于 2018-09-04 14:58:52

试试以下:

代码语言:javascript
复制
        [DllImport("LibName", EntryPoint = "get_texts", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        private static extern IntPtr GetTexts();

        static void Main(string[] args)
        {
            List<string> results = new List<string>();

            IntPtr data = GetTexts();

            IntPtr tmpPtr = IntPtr.Zero;
            while(data != null)
            {
                string str = Marshal.PtrToStringAnsi(data);
                results.Add(str);
                data += 1;
            }
        }

代码假定字符串数组存储为点数组。在某些时候,情况并非如此,然后下面的代码可能会起作用

代码语言:javascript
复制
            [DllImport("LibName", EntryPoint = "get_texts", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
            private static extern IntPtr GetTexts();

            static void Main(string[] args)
            {
                List<string> results = new List<string>();

                IntPtr data = GetTexts();

                IntPtr tmpPtr = IntPtr.Zero;
                Boolean first = true;
                string str = "";
                do
                {
                    if (first)
                    {
                        str = Marshal.PtrToStringAnsi(data);
                        first = false;
                    }
                    results.Add(str);
                    data += str.Length + 1;
                    str = Marshal.PtrToStringAnsi(data);

                } while (str.Length > 0);
            }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100002554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档