2015-12-19 2 views
0

Я использую код C# и должен вызывать этот метод внутри dll C++.Вызов метода wstring C++ из C#

static std::wstring DecryptData(const std::wstring& strKey); 

Я прочитал много вещей, и мое лучшее предположение было бы передать то, что легче читать на обоих языках, как полукокса массива или даже байт-массив и построить wstring в C++ и строку в C# после.

Кто-нибудь сделал это уже?

Edit:

Я прочитал linkes тема, но ни один из ответов не помогает мне: Использование const не помогло.

Это то, что я сейчас: C#

[DllImport(DLL_PATH, CharSet = CharSet.Unicode)] 
     [return: MarshalAs(UnmanagedType.LPWStr)] 
     public static extern string DecryptData([MarshalAs(UnmanagedType.LPWStr)]string strKey); 

C++

extern "C" __declspec(dllexport) const std::wstring DecryptData(const std::wstring& strKey) { 
    return WlanHelper::CWirelessHelper::DecryptData(strKey); 
} 

Это дает мне PInvokeStackImbalance =/

+0

Возможный дубликат [Возвратить зЬй :: wstring из C++ в C#] (HTTP: //stackoverflow.com/questions/7051097/return-a-stdwstring-from-c-into-c-sharp) – kevindeleon

+0

Это сводит вторую половину моего вопроса. Но мне также нужно ввести строку C#, и метод ожидает wstring atm. – ecth

+0

'[DllImport (" path.dll ", CharSet = CharSet.Unicode)] static extern string DecryptData ([MarshalAs (UnmanagedType.LPWStr)] string strKey);'? – drf

ответ

2

Вы можете найти this question и this question быть актуальной. Есть два вопроса:

  1. P/Invoke изначально не маршал std::string/std::wstring и
  2. Возможных проблем прижизненных памятей (в зависимости от реализации CWirelessHelper::DecryptData).

подход заключается в копировании строки в простом wchar_t* буфера, выделенного с помощью CoTaskMemAlloc (the framework will handle the string conversion and free the allocated memory).

На неуправляемом стороне, код становится:

extern "C" __declspec(dllexport) const wchar_t* DecryptData(wchar_t* strKey) { 
    std::wstring retstr = WlanHelper::CWirelessHelper::DecryptData(std::wstring(strKey)); 
    const wchar_t* ret = retstr.c_str(); 
    size_t bufsize = wcslen(ret) + 1; 
    wchar_t* buffer = (wchar_t*)CoTaskMemAlloc(bufsize * sizeof(wchar_t)); 
    wcscpy_s(buffer, bufsize, ret); 
    return buffer; 
} 

А на управляемой стороне:

[DllImport(DLL_PATH, 
    CharSet = CharSet.Unicode, 
    CallingConvention = CallingConvention.Cdecl)] 
static extern string DecryptData(string strKey); 
+0

Спасибо! Оно работает! – ecth