4

次のC++関数があります

void FillAndReturnString(char ** someString)
{
   char sourceString[] = "test";
   *someString = new char[5];
   memcpy(*someString, sourceString, 5);   
}

次のように宣言されています

extern "C"
{
__declspec(dllexport) void __cdecl FillAndReturnString(char ** someString);
}

C# からこの関数を呼び出すにはどうすればよいですか?

ありがとう

4

2 に答える 2

1

P/Invokeを使用します。

于 2009-06-24T22:03:23.560 に答える
1

C++ 関数でアンマネージ メモリ ブロックを割り当てていることを知っておく必要があるため、C# コードからマネージド String または Array オブジェクトを渡して char 配列を「保持」することはできません。

1 つの方法は、ネイティブ dll で「削除」関数を定義し、それを呼び出してメモリの割り当てを解除することです。マネージド側では、IntPtr構造体を使用して、c++ char 配列へのポインターを一時的に保持できます。

// c++ function (modified)
void __cdecl FillAndReturnString(char ** someString)
{
   *someString = new char[5];
   strcpy_s(*someString, "test", 5);   // use safe strcpy
}

void __cdecl DeleteString(char* someString)
{
   delete[] someString
}


// c# class
using System;
using System.Runtime.InteropServices;

namespace Example
{
   public static class PInvoke
   {
      [DllImport("YourDllName.dll")]
      static extern public void FillAndReturnString(ref IntPtr ptr);

      [DllImport("YourDllName.dll")]
      static extern public void DeleteString(IntPtr ptr);
   }

   class Program
   {
      static void Main(string[] args)
      {
         IntPtr ptr = IntPtr.Zero;
         PInvoke.FillAndReturnString(ref ptr);

         String s = Marshal.PtrToStringAnsi(ptr);

         Console.WriteLine(s);

         PInvoke.Delete(ptr);
      }
   }

}

于 2009-06-24T23:22:53.650 に答える