簡體   English   中英

如何在消息框中顯示帶有WCHAR *的C#中的C函數

[英]how to display in messagebox a C function from C# with a WCHAR*

我正在構建一個加載C ++庫的C#應用​​程序。 我從該C ++ DLL調用函數。 我使用下面的功能來顯示輸入字符串。

C ++ DLL:

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

return HWStr.c_str();
}

C#代碼:

[DllImport("testDll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]

public static extern int  _Test_EchoString([MarshalAs(UnmanagedType.LPWStr)] string s);

private void echo_string_Click(object sender, RoutedEventArgs e)
{
    string upn = "aaaaa";
    _Test_EchoString(upn);

    MessageBox.Show(_Test_EchoString(upn).ToString());    
}

我進入消息框編號18666252,但我想從_Test_EchoString()獲得一個字符串。

您的代碼中有兩個問題:

在您的C#中,您將_Test_EchoString定義為public static extern int _Test_EchoString ,因此在執行它時,返回值將是字符串HWStr.c_str()的第一個字符的地址。 正如安德拉斯所說,這里顯示了另一個問題,您正在返回一個無效的指針,因為HWStr.c_str()將指針返回到std::wstring對象的當前值,因此只要wstring有效,它就有效,因此當方法Test_EchoString結束執行時,它不再有效(因為HWStr被銷毀)。

有多種方法可以解決此問題,我將向您介紹以下兩種方法:

1)第一種是在Heap中分配要返回的內存,並在以后通過另一個調用將其釋放:

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#中的用法:

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

對我來說,這看起來很丑陋,所以我寧願使用其他模式

2)將回調傳遞給C方法,並在HWStr仍然有效時傳遞給該方法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#的用法:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM