stronciy
@stronciy

Получить в .NET строку из С++ dll

Ув. спецы нужна помощь, две недели выброшены из жизни, итак

Есть dll написанная на С++ с очень простым содержанием

void IsolatedFunction()
{

cout << "Redirected string1" << endl << "Redirected string2" << endl;

}


Вопрос, как вывзвать в .NET это функцию и получить результат ее работы?

Вопрос не так прост, как кажется, если делать return(«bla bla bla») в С++ то все работает отлично, как только появляется stdout то начинаются кошмарики.

В результате рытья сети через гугл нашел почти то что нужно, работат как надо но!!! срабатывает один раз, при повторном вызове получется висяк…

Зарание благодарен за помощь.
  • Вопрос задан
  • 2642 просмотра
Пригласить эксперта
Ответы на вопрос 2
ertaquo
@ertaquo
Попробуйте не создавать по несколько раз экземпляр AnonymousPipeServerStream, а создать его один раз и один раз вызвать SetStdHandle, далее вызывая server.Flush();, затем функцию из дллки и чтение из пайпа. В-общем, что-то в этом роде (работоспособность не проверял):
Copy Source | Copy HTML
  1. public static class ConsoleOutRedirector
  2. {
  3.     #region Constants
  4.  
  5.     private const Int32 STD_OUTPUT_HANDLE = -11;
  6.  
  7.     #endregion
  8.  
  9.     #region Externals
  10.  
  11.     [DllImport("Kernel32.dll")]
  12.     extern static Boolean SetStdHandle(Int32 nStdHandle, SafeHandleZeroOrMinusOneIsInvalid handle);
  13.     [DllImport("Kernel32.dll")]
  14.     extern static SafeFileHandle GetStdHandle(Int32 nStdHandle);
  15.  
  16.     #endregion
  17.  
  18.     #region Variables
  19.  
  20.     private static AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out);
  21.     private static client = new AnonymousPipeClientStream(PipeDirection.In, server.ClientSafePipeHandle);
  22.     private static bool First = true;
  23.  
  24.     #endregion
  25.  
  26.     #region Methods
  27.  
  28.     public static String GetOutput(Action action)
  29.     {
  30.         Debug.Assert(action != null);
  31.  
  32.         using (server)
  33.         {
  34.             if (First)
  35.             {
  36.                 var defaultHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  37.  
  38.                 Debug.Assert(!defaultHandle.IsInvalid);
  39.                 Debug.Assert(SetStdHandle(STD_OUTPUT_HANDLE, server.SafePipeHandle));
  40.                 try
  41.                 {
  42.                     action();
  43.                 }
  44.                 finally
  45.                 {
  46.                     Debug.Assert(SetStdHandle(STD_OUTPUT_HANDLE, defaultHandle));
  47.                 }
  48.  
  49.                 First = false;
  50.             }
  51.  
  52.             server.Flush();
  53.             client.Flush();
  54.  
  55.             using (client)
  56.             {
  57.                 using (var reader = new StreamReader(client))
  58.                 {
  59.                     using (var writer = new StringWriter())
  60.                     {
  61.                         while (reader.Peek() != -1)
  62.                         {
  63.                             writer.Write(Convert.ToChar(reader.Read()));
  64.                         }
  65.                         return writer.ToString();
  66.                     }
  67.                 }
  68.             }
  69.         }
  70.     }
  71.  
  72.     #endregion
  73. }
  74.  
Ответ написан
ertaquo
@ertaquo
А если что-то наподобие этого (источник), без заморочек со SetStdHandle и пайпами? К сожалению, C# знаю довольно плохо, так что могу только методом тыка советовать =\
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы