С# обмен данными с DLL C++ - C#
Формулировка задачи:
Здравствуйте уважаемые ГУРУ!
С++:
Функция DLL на с++
в результате работы формирует строку типа_bstr_t
Эту строку нужно передать в код наС#
Делаю ледующим образом: 1. На С# получаю указатель на выделенный блок памяти и передаю его параметром в функцию dll на С++ 2. В DLL создается строка с типом _bstr_t ID, которая преобразуется в массив char и записывается по адресу переданному из С#в параметре Проблема: В С# приходит не вся строка, а только"BaseBoard="
Само значение _bstr_t BaseBoard не передается. То есть передается толькоконстантная часть
строки ID Если передатьтолько переменную_bstr_t BaseBoard
то выскакивает исключение что передаваемое значение не может быть NULL Хотя когда DLL функция тестируется как консольное приложение то все работает, Переменная _bstr_t ID содержит и константную часть и значение переменной _bstr_t BaseBoard. Помогите пожалуйста найти грабли. Заранее благодарен всем откликнувшимся . С#[DllImport(@"D:\\ProjectsC++\\DLL\\MyDLL\\Debug\\MyDLL.dll", EntryPoint = "GetString", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern int GetString(IntPtr pComputerName); var pComputerName = Marshal.AllocHGlobal(256); // Вызываем описанную внешнюю функцию GetString(pComputerName, ref size); // Переводим результат в управляемый вид var str = Marshal.PtrToStringUni(pComputerName); //Освобождаем выделенную память Marshal.FreeHGlobal(pComputerName);
define _WIN32_DCOM #include <iostream> using namespace std; #include <comdef.h># #include <Wbemidl.h> #pragma comment(lib, "wbemuuid.lib") extern "C" __declspec(dllexport) int GetString(char *pMemory) { HRESULT hres; // Step 1: -------------------------------------------------- // Initialize COM. ------------------------------------------ hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl; return 1; // Program has failed. } // Step 2: -------------------------------------------------- // Set general COM security levels -------------------------- hres = CoInitializeSecurity( NULL, -1, // COM authentication NULL, // Authentication services NULL, // Reserved RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation NULL, // Authentication info EOAC_NONE, // Additional capabilities NULL // Reserved ); if (FAILED(hres)) { cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl; CoUninitialize(); return 1; // Program has failed. } // Step 3: --------------------------------------------------- // Obtain the initial locator to WMI ------------------------- IWbemLocator *pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc); if (FAILED(hres)) { cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl; CoUninitialize(); return 1; // Program has failed. } // Step 4: ----------------------------------------------------- // Connect to WMI through the IWbemLocator::ConnectServer method IWbemServices *pSvc = NULL; // Connect to the root\cimv2 namespace with // the current user and obtain pointer pSvc // to make IWbemServices calls. hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace NULL, // User name. NULL = current user NULL, // User password. NULL = current 0, // Locale. NULL indicates current NULL, // Security flags. 0, // Authority (for example, Kerberos) 0, // Context object &pSvc // pointer to IWbemServices proxy ); if (FAILED(hres)) { cout << "Could not connect. Error code = 0x" << hex << hres << endl; pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl; // Step 5: -------------------------------------------------- // Set security levels on the proxy ------------------------- hres = CoSetProxyBlanket( pSvc, // Indicates the proxy to set RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx NULL, // Server principal name RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx NULL, // client identity EOAC_NONE // proxy capabilities ); if (FAILED(hres)) { cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } // Step 6: -------------------------------------------------- // Use the IWbemServices pointer to make requests of WMI ---- // For example, get the name of the operating system IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_BaseBoard"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); if (FAILED(hres)) { cout << "Query for operating system name failed." << " Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } // Step 7: ------------------------------------------------- // Get the data from the query in step 6 ------------------- IWbemClassObject *pclsObj = NULL; ULONG uReturn = 0; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if(0 == uReturn) { break; } VARIANT vtProp; // Get the value of the Name property hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); //BSTR vtProp _bstr_t BaseBoard(vtProp.bstrVal); _bstr_t ID = "BaseBoard=" + BaseBoard; [B]//преобразуем _bstr_t ID в массив char и записываем его по переданному в параметре адресу[/B] strcpy_s(pMemory, ID.length() + 1, (LPCSTR)ID); VariantClear(&vtProp); pclsObj->Release(); } // Cleanup pSvc->Release(); pLoc->Release(); pEnumerator->Release(); CoUninitialize(); return 0; }
Решение задачи: «С# обмен данными с DLL C++»
textual
Листинг программы
string wmiQuery = "SELECT * FROM Win32_OperatingSystem"; using(ManagementObjectSearcher searcher = new ManagementObjectSearcher ( wmiQuery )) { ManagementObjectCollection retObjectCollection = searcher.Get ( ); foreach (ManagementObject retObject in retObjectCollection) { string result = retObject["Name"]; break; } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д