C# 外部C/C++;库不在C中打印# 我从C++调用了一个C++外部库。Return有效,但是printf()不会在控制台窗口中打印数据。为什么会这样?我做错什么了吗

C# 外部C/C++;库不在C中打印# 我从C++调用了一个C++外部库。Return有效,但是printf()不会在控制台窗口中打印数据。为什么会这样?我做错什么了吗,c#,c++,dll,pinvoke,C#,C++,Dll,Pinvoke,即使我调用DisplayHelloFromDLL而不将其返回值指定给变量x,打印文本也不会显示在屏幕上 C++: 我认为,您的问题是DLL没有分配控制台-它不应该知道C#控制台。也许,您可以尝试将对C#Console对象的引用传递给“DisplayHelloFromDLL”函数。 但我从未尝试过它-我不知道如何从C/C++DLL访问/使用C#Console对象。您的C外部库可能无法访问任何输出控制台。您可以使用以下函数写入输出控制台 根据此线程()调试时存在的Visual Studio宿主进

即使我调用
DisplayHelloFromDLL
而不将其返回值指定给变量x,打印文本也不会显示在屏幕上

C++:


我认为,您的问题是DLL没有分配控制台-它不应该知道C#控制台。也许,您可以尝试将对C#Console对象的引用传递给“DisplayHelloFromDLL”函数。
但我从未尝试过它-我不知道如何从C/C++DLL访问/使用C#Console对象。

您的C外部库可能无法访问任何输出控制台。您可以使用以下函数写入输出控制台

根据此线程()调试时存在的Visual Studio宿主进程是DLL的控制台输出无法到达控制台的原因

检查这一点的一个简单方法是直接运行可执行文件,而不是通过IDE的调试器。如果这确实证实了这种情况,那么您可以根据需要禁用托管进程,如链接线程中所述

您的代码还有两个问题:

[DllImport("Hello.dll", EntryPoint = "DisplayHelloFromDLL")]
public static extern string DisplayHelloFromDLL();

默认的P/VoCK调用约定为“代码> STDCALL//CODE”,但默认C++调用约定是“代码> CCDLL < /代码>。因此,您的C#p/invoke使用了错误的调用约定。您需要更改其中一个声明来解决此问题


将返回类型声明为
string
意味着封送拆收器将尝试通过调用
CoTaskMemFree
来释放返回的指针。C字符串未分配给
CoTaskMemAlloc
,因此这是未定义的行为。您应该声明返回类型为“代码> ItpTrt/CODE >,并使用<代码> MARSHAL.PtrtoStrangnsi获取字符串,记住C++代码返回不应该(确实不能)释放的文字。或者,使用其他多种方法中的一种返回字符串,该字符串在确定内存所有权方面可能更清晰。

没有显示C代码。你是说C++,是的,抱歉我会编辑这个问题。然而,我不明白为什么有人否决了它。你在C端以这种方式处理
char*
返回类型。您的代码尝试取消分配指针调用
CoTaskMemFree
。将返回类型声明为
IntPtr
,并使用
marshall.PtrToStringAnsi
@DavidHeffernan获取一个字符串,实际上返回的数据工作正常。但是C中的“printf()”不会在控制台中打印“Hello from DLL”。@DavidHeffernan它怎么会不工作?它正在屏幕上打印“某物”。我们谈论的是同样的事情吗?实际上这很有帮助:“一种简单的检查方法是直接运行可执行文件,而不是通过IDE的调试器。如果确实如此,那么您可以根据需要禁用托管进程,如链接线程中所述。”。它的工作,但我必须启动这个应用程序从其他cmd窗口。
using System;
using System.Runtime.InteropServices;



class HelloWorld
{

    [DllImport("Hello.dll", EntryPoint = "DisplayHelloFromDLL")]
    public static extern string DisplayHelloFromDLL();

    static void Main()
    {
        Console.WriteLine("This is C# program");
        string x = DisplayHelloFromDLL();
        Console.WriteLine(x);
        Console.ReadKey();
    }

}
[DllImport("Hello.dll", EntryPoint = "DisplayHelloFromDLL")]
public static extern string DisplayHelloFromDLL();