如何使用WCHAR在messagebox中显示来自C#的C函数* 我正在构建一个C C++应用程序,它加载C++库。 我从C++ DLL调用函数。我使用下面的函数来显示输入字符串

如何使用WCHAR在messagebox中显示来自C#的C函数* 我正在构建一个C C++应用程序,它加载C++库。 我从C++ DLL调用函数。我使用下面的函数来显示输入字符串,c#,c++,wpf,interop,dllimport,C#,C++,Wpf,Interop,Dllimport,c++dll: wchar_t* Test_EchoString( wchar_t *InputStr ) { String HWStr = String( InputStr ); return HWStr.c_str(); } c#代码: 我进入了messagebox编号18666252,但我想从\u Test\u EchoString()中获取一个字符串。您的代码中有两个问题: 在C中,您将\u Test\u EchoString定义为public static extern int

c++dll:

wchar_t* Test_EchoString( wchar_t *InputStr )
{
String HWStr = String( InputStr );  

return HWStr.c_str();
}
c#代码:


我进入了messagebox编号18666252,但我想从
\u Test\u EchoString()
中获取一个字符串。您的代码中有两个问题:


在C中,您将
\u Test\u EchoString
定义为
public static extern int\u Test\u EchoString
,因此在执行它时,返回的值将是字符串
HWStr.C\u str()
的第一个字符的地址。 这里它显示了另一个问题,正如anderas所说,您返回的指针无效,因为
HWStr.c_str()
返回指向
std::wstring
对象当前值的指针,因此只要
wstring
有效,因此,当方法
Test\u EchoString
结束其执行时,它不再有效(因为
HWStr
被销毁)

有不同的方法可以解决此问题,我将向您展示其中两种:

1)第一步是分配要在堆中返回的内存,然后通过另一个调用释放它:

static wchar_t *Test_EchoStringResult;
extern "C" __declspec(dllexport) const wchar_t * Test_EchoStringNew(const wchar_t *InputStr)
{
    std::wstring HWStr(InputStr);
    HWStr += L" something";
    Test_EchoStringResult = new wchar_t[HWStr.length() + sizeof(wchar_t)];
    HWStr.copy(Test_EchoStringResult, HWStr.length());
    Test_EchoStringResult[HWStr.length()] = L'\0';
    return Test_EchoStringResult;
}

extern "C" __declspec(dllexport) void Test_EchoStringDelete()
{
    delete[] Test_EchoStringResult;
}
这就是C#中的用法:

对我来说,这看起来很难看,所以我更喜欢使用另一种模式

2)
HWStr
仍然有效时,将回调传递给C方法并传递给此方法
HWStr.C_str()

extern "C" __declspec(dllexport) void Test_EchoString(const wchar_t *InputStr, void (*callback)(const wchar_t*))
{
    std::wstring HWStr(InputStr);
    HWStr += L" something";
    callback(HWStr.c_str());
}
下面是C#的用法:


等待当HWStr超出作用域时,它不会被销毁吗?因此,HWStr.c_str()返回的指针会变得无效?
\u Test\u EchoString
返回一个整数(
公共静态外部int\u Test\u EchoString
)。int.ToString返回
wchar\u t*Test\u EchoString(wchar\u t*InputStr)
方法中的
string
数字的字符串表示形式?是不是
std::wstring
?谢谢您的建议
[DllImport("testDll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern IntPtr Test_EchoStringNew(string foo);

[DllImport("testDll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern void Test_EchoStringDelete();

public void foo()
{
    string result = Marshal.PtrToStringAuto(Test_EchoStringNew("test"));
    MessageBox.Show(result.ToString());
    Test_EchoStringDelete();
}
extern "C" __declspec(dllexport) void Test_EchoString(const wchar_t *InputStr, void (*callback)(const wchar_t*))
{
    std::wstring HWStr(InputStr);
    HWStr += L" something";
    callback(HWStr.c_str());
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public delegate void myCallback(string toShow);

[DllImport("testDll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern void Test_EchoString(string foo, myCallback callback);

public void foo()
{
    Test_EchoString("test", callback);
}

void callback(string toShow)
{
    MessageBox.Show(toShow);
}