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

Viewed 119

I am trying to output text from a C++ function to a textbox in WPF, but when I click the button it outputs nothing. In the C# Console it worked.

Here the code from the C# console:

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();
        }
    }
}

Here the code from the C++ DLL:

using namespace std;


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

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

Here the code from the C# WPF page:

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();
        }
        
    }
}

What do I have to do so that the text from the text_output() function is output to the textbox when I click the button?

1 Answers

On Windows (which WPF implies you are using), the BSTR can be created from standard wide-string, and you can try C++ code like:

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

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

// ...

Then wrap into string with MarshalAs in your C# declaration, like:

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

P.S. You may need to convert char * to Wide-String, something like:

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;
}
Related