C# 从导入的DLL抑制控制台打印 在C++控制台应用程序中,我导入了一个本地C++ DLL方法。例如: [DllImport("MyDll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] public static extern int MyMethod(IntPtr somePointer);

C# 从导入的DLL抑制控制台打印 在C++控制台应用程序中,我导入了一个本地C++ DLL方法。例如: [DllImport("MyDll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] public static extern int MyMethod(IntPtr somePointer);,c#,c++,console,dllimport,C#,C++,Console,Dllimport,执行时,MyMethod()将输出打印到控制台,我希望将其隐藏 假设我不能更改DLL,我怎么还能抑制它的输出呢?唯一的方法是在调用DLL时重定向标准输出。我从未尝试过,也不知道它是否有效 使用setstdhold将标准输出定向到其他位置。例如,nul设备的句柄就可以了。如果在调用DLL返回后需要恢复原始的标准输出句柄,则需要再次调用setstdhold 每次调用DLL时,您都需要跳过这些限制。如果您有线程和/或回调,事情会变得更加复杂。修改自 我删除了他们试图重定向的部分,因为如果你进一步阅读,

执行时,
MyMethod()
将输出打印到控制台,我希望将其隐藏


假设我不能更改DLL,我怎么还能抑制它的输出呢?

唯一的方法是在调用DLL时重定向标准输出。我从未尝试过,也不知道它是否有效

使用
setstdhold
将标准输出定向到其他位置。例如,nul设备的句柄就可以了。如果在调用DLL返回后需要恢复原始的标准输出句柄,则需要再次调用
setstdhold

每次调用DLL时,您都需要跳过这些限制。如果您有线程和/或回调,事情会变得更加复杂。

修改自

我删除了他们试图重定向的部分,因为如果你进一步阅读,它会说他们在多次调用时遇到了问题

 public static class ConsoleOutRedirector
    {
    #region Constants

    private const Int32 STD_OUTPUT_HANDLE = -11;

    #endregion

    #region Externals

    [DllImport("Kernel32.dll")]
    extern static Boolean SetStdHandle(Int32 nStdHandle, SafeHandleZeroOrMinusOneIsInvalid handle);
    [DllImport("Kernel32.dll")]
    extern static SafeFileHandle GetStdHandle(Int32 nStdHandle);

    #endregion

    #region Methods

    public static void GetOutput(Action action)
    {
      Debug.Assert(action != null);

      using (var server = new AnonymousPipeServerStream(PipeDirection.Out))
      {
        var defaultHandle = GetStdHandle(STD_OUTPUT_HANDLE);

        Debug.Assert(!defaultHandle.IsInvalid);
        Debug.Assert(SetStdHandle(STD_OUTPUT_HANDLE, server.SafePipeHandle));
        try
        {
          action();
        }
        finally
        {
          Debug.Assert(SetStdHandle(STD_OUTPUT_HANDLE, defaultHandle));
        }
      }
    }

    #endregion
  }
和使用示例:

[DllImport("SampleLibrary.dll")]
extern static void LetterList();

private void button1_Click(object sender, EventArgs e)
{
  ConsoleOutRedirector.GetOutput(() => LetterList());
}

那需要一部电话。你用来打电话给DLL的作者并要求他更改代码的那个。现在,让我们假设我没有电话。:)一定有办法…如果你确定你可以使用两个过程。。。一个用于应用程序,另一个用于托管DLL。托管DLL的那个可能根本没有UI。您可以使用进程间通信,也可以使用返回代码与API通信。这将是非常混乱的,虽然。。。将应用程序创建为窗体应用程序而不是控制台应用程序可能更容易。不过,阅读David Heffernan的回复,我不确定它在线程/回调方面的效果如何。