C++ DLL 的函数不在 WPF 中输出文本

Function of a C++ DLL does not output text in WPF

我试图将文本从 C++ 函数输出到 WPF 中的文本框,但是当我单击该按钮时它没有输出任何内容。 它在 C# 控制台中有效。

这里是来自 C# 控制台的代码:

namespace ConsoleApp1
{

    class Program
    {
        const string dllfile = "C:\...";
        [DllImport(dllfile, EntryPoint = "main", CallingConvention = CallingConvention.Cdecl)]
        private static extern string text_output();

        static void Main(string[] args)
        {
            text_output();
        }
    }
}

这里是 C++ DLL 中的代码:

using namespace std;


void text_output();
void text_output()
{
    cout << "something" << endl;
}

extern "C" __declspec(dllexport) int main()
{
    text_output();
    return 0;
}

这里是 C# WPF 页面中的代码:

namespace application
{
    public partial class Page1 : Page
    {
        const string dllfile = "C:\...";
        [DllImport(dllfile, EntryPoint = "main", CallingConvention = CallingConvention.Cdecl)]
        private static extern string text_output();
        
        public Page1()
        {
            InitializeComponent();
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            txtBox.Text += text_output();
        }
        
    }
}

当我单击按钮时,我必须做什么才能将 text_output() 函数的文本输出到文本框?

在 Windows 上(WPF 表示您正在使用),BSTR 可以从标准宽字符串创建,您可以尝试 C++ 代码,例如:

#include <windows.h> // For BSTR from "wtypes.h" header.

extern "C" __declspec(dllexport) BSTR text_output()
{
    return ::SysAllocString(L"something");
}

// ...

然后在 C# 声明中用 MarshalAs 包装成 string,例如:

const string dllfile = "C:\...";
[DllImport(dllfile, EntryPoint = "main", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string text_output();

P.S。您可能需要将 char * 转换为宽字符串,例如:

BSTR StrToBSTR(const char *value) {
    int valueLength = lstrlenA(value);
    if (valueLength > 0) {
        int resultLength = ::MultiByteToWideChar(CP_ACP, 0, value, valueLength, NULL, 0);
        if (resultLength > 0) {
            BSTR result = ::SysAllocStringLen(0, resultLength);
            ::MultiByteToWideChar(CP_ACP, 0, value, valueLength, result, resultLength);
            return result;
        }
    } 
    return NULL;
}