C#调用C++编写的DLL中的函数,返回值是string 类型的指针,应该怎样处理?

时间:2022-08-31 09:11:47
GETSN_API string* abc(void)
{
string* test = new string[100];
test[0] = "0000";
test[1] = "0000";
return test;
}


C#调用函数abc()后,怎样得到他的返回值呢?

或者是C#怎样申请一个C++中的字符串数组,传递给函数,并返回呢?

11 个解决方案

#1


stringbuild

#2


楼上正解

#3


System.Text.StringBuilder 

#4


那如果是Char* 类型呢?

#5


stringbuild

#6


这里返回的是一个string数组
用string[]接收


所有的字符串类型都可以用string接收

#7



StringBuilder s = new StringBuilder();
s = TEST();  // 调用DLL中的方法,返回char*



程序调通了,但是s里面是 乱码  !!!

怎么回事呢?

#8


字符串数组的大小没有传回来,所以基本无法得到所有的字符串。
楼主可以这样来改:

#include <string>
using namespace std;

extern "C"
__declspec(dllexport)
int abc(string*& test)
{
    test = new string[100];
    test[0] = "test[0]";
    test[1] = "test[1]";
    return 2;
}



using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace ConsoleApplication1 {
    class Program {
        [DllImport("MyCppDll.dll")]
        public static extern int abc(ref IntPtr test);

        public static void Main() {
            IntPtr ptr = new IntPtr();
            List<string> results = new List<string>();
            int size = abc(ref ptr);

            IntPtr current = new IntPtr(ptr.ToInt32() + IntPtr.Size);
            string temp = null;
            for (int i = 0; i < size; i++) {
                temp = Marshal.PtrToStringAnsi(current);
                results.Add(temp);
                current = new IntPtr(current.ToInt32() + temp.Length * IntPtr.Size);
            }

            foreach (string result in results) {
                Console.WriteLine(result);
            }

            Console.ReadLine();
        }
    }
}


关于字符串或者字符串数组的P/Invoke,你可以看看这个文章:
http://www.codeproject.com/KB/cs/marshalarrayofstrings.aspx

#9


谢谢。。。

#10


你的问题主要就是平台调用过程中的数据封送问题。使用StringBuilder或IntPtr进行封送都是可以的。

如果你想系统学习如何进行数据封送,我推荐你阅读刚刚出版的新书:《精通.NET互操作P/Invoke,C++Interop和COM Interop》,这本书的第2章“数据封送”详细介绍了平台调用中的数据封送过程,非常详细,我就是读完后才搞清楚平台调用中的封送处理。 


该书的官方网站: 
www.interop123.com 

豆瓣网信息: 
http://www.douban.com/subject/3671497/ 

#11


参考一下,呵呵。

#1


stringbuild

#2


楼上正解

#3


System.Text.StringBuilder 

#4


那如果是Char* 类型呢?

#5


stringbuild

#6


这里返回的是一个string数组
用string[]接收


所有的字符串类型都可以用string接收

#7



StringBuilder s = new StringBuilder();
s = TEST();  // 调用DLL中的方法,返回char*



程序调通了,但是s里面是 乱码  !!!

怎么回事呢?

#8


字符串数组的大小没有传回来,所以基本无法得到所有的字符串。
楼主可以这样来改:

#include <string>
using namespace std;

extern "C"
__declspec(dllexport)
int abc(string*& test)
{
    test = new string[100];
    test[0] = "test[0]";
    test[1] = "test[1]";
    return 2;
}



using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace ConsoleApplication1 {
    class Program {
        [DllImport("MyCppDll.dll")]
        public static extern int abc(ref IntPtr test);

        public static void Main() {
            IntPtr ptr = new IntPtr();
            List<string> results = new List<string>();
            int size = abc(ref ptr);

            IntPtr current = new IntPtr(ptr.ToInt32() + IntPtr.Size);
            string temp = null;
            for (int i = 0; i < size; i++) {
                temp = Marshal.PtrToStringAnsi(current);
                results.Add(temp);
                current = new IntPtr(current.ToInt32() + temp.Length * IntPtr.Size);
            }

            foreach (string result in results) {
                Console.WriteLine(result);
            }

            Console.ReadLine();
        }
    }
}


关于字符串或者字符串数组的P/Invoke,你可以看看这个文章:
http://www.codeproject.com/KB/cs/marshalarrayofstrings.aspx

#9


谢谢。。。

#10


你的问题主要就是平台调用过程中的数据封送问题。使用StringBuilder或IntPtr进行封送都是可以的。

如果你想系统学习如何进行数据封送,我推荐你阅读刚刚出版的新书:《精通.NET互操作P/Invoke,C++Interop和COM Interop》,这本书的第2章“数据封送”详细介绍了平台调用中的数据封送过程,非常详细,我就是读完后才搞清楚平台调用中的封送处理。 


该书的官方网站: 
www.interop123.com 

豆瓣网信息: 
http://www.douban.com/subject/3671497/ 

#11


参考一下,呵呵。