5

我在用 c++ 创建的 dll 中有这个

extern "C" __declspec(dllexport)
    char*  __stdcall hh()
{
    char a[2];
    a[0]='a';
         a[1]='b';
    return(a);
}

这就是我试图在 c# 中处理代码的方式

[DllImport(@"mydll.dll",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.StdCall)]     
       public static extern IntPtr hh();
       static void Main(string[] args)
        {
            IntPtr a = hh();
           //How to proceed here???
        }


    }

帮助进一步进行。

4

4 回答 4

3

没有办法处理这样的数组。char a[2]在 C++ 函数的堆栈上分配,并在您从它返回时立即销毁。您应该从 C# 传递一个数组并将其填充到 C++ 代码中,或者在堆中分配数组并提供一些释放它的方法。

当您正确处理时,将取决于您如何从 C++ 代码返回数据。如果它仍然是 IntPtr ,则可以使用 Marshal.ReadByte 方法从内存中读取字符,并在必要时使用 Encoding 方法将这些字节转换为字符串。


const int bufferSize = 2; // suppose it's some well-known value.
IntPtr p = ...; // get this pointer somehow.
for (var i = 0; i != bufferSize; ++i)
{
  var b = Marshal.ReadByte(p, i);
  Console.WriteLine(b);
}

于 2012-04-10T09:57:15.983 回答
2

我得到了如下解决方案::

我们的 C++ 代码如下

extern "C" __declspec(dllexport)
    char**  __stdcall hh()
{
 static char* myArray[3] = {"A1", "BB2", "CC3",};
    return myArray;
}

C#如下

[DllImport(@"ourdll.dll",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.StdCall)]     
      public static extern IntPtr hh();
       static void Main(string[] args)
        {
            IntPtr a = hh();
            int j = 0;
            string[] s=new string[100];
           do
           {
               s[j] = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(a,4*j));
               j++;
           }
           while(s[j-1] != null);
        }

现在面临的唯一问题是我们如何知道数组的大小,以便在这个语句中 string[] s=new string[100]; 我们不必浪费我们的记忆。

于 2012-04-11T05:04:52.510 回答
1

答案是

 string stra = Marshal.PtrToStringAnsi(a);

但是您也有一个问题,即 dll 根据您的代码返回垃圾,因为 char* 是本地 c 样式字符串。如果你能返回类似的东西就可以了:

 const char* str = "Hello from DLL.";
于 2012-04-10T09:14:04.420 回答
-2

尝试使用非空 StringBuilder 作为返回值。

于 2012-04-10T08:41:19.937 回答