powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Получить данные из метода на Си++ в Си#
15 сообщений из 15, страница 1 из 1
Получить данные из метода на Си++ в Си#
    #38377558
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не получается получить данные из метода в сишной дллке.
Код на плюсах:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
__declspec(dllexport) wchar_t* GetID1();
...
wchar_t* GetID()
{
	wchar_t* result=(wchar_t*)malloc(128);
	result[0] = '\0';
	wcscat(result, L"ляля тополя");	
	return result;
}



Код на шарпе:
Код: c#
1.
2.
[DllImport("MyDll.dll", EntryPoint = "GetID", CharSet = CharSet.Unicode)]
private static extern string GetID();


...
Код: c#
1.
var sn = GetID();



При вызове метода GetID срабатывает исключение:
Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.

Что делаю не так, чего не хватает?
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38377562
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
метод называется GetID, вверху опечатка (GetID1 - неправильное название)
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38377573
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пробовал через параметры:
Код: plaintext
1.
2.
3.
4.
5.
6.
void GetID(wchar_t* result)
{
	result=(wchar_t*)malloc(128);
	result[0] = '\0';
	wcscat(result, L"ляля тополя");		
}



результат тот же.. Как определить аут параметр? wchar_t** ? непомогло
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38377576
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
result=(wchar_t*)malloc(128);
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38377628
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Погуглил, в итоге наработал такой вариант:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
__declspec(dllexport) void GetID(wchar_t*);

...

void GetID(wchar_t* w)
{
	w = L"test";
}



c#:
Код: c#
1.
2.
3.
4.
5.
6.
7.
[DllImport("ND.Base.dll", EntryPoint = "GetID")]
static extern void GetID1([MarshalAs(UnmanagedType.BStr)] out string result);

...

string sn;
GetID(out sn);



исключения больше нет, но значение переменной равно null.
wtf?
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38377911
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ниггадяй,

c# не сможет нормально работать с результатом malloc (не сможет освободить память, в частности)
вариантов несколько
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
extern "C" __declspec(dllexport) BSTR GetID();

BSTR GetID()
{
	BSTR result= ::SysAllocString( L"ляля тополя");	
	return result;
}



Код: c#
1.
2.
3.
        [DllImport("MyDll.dll")]
        [return:MarshalAs( UnmanagedType.BStr)]
        private static extern string GetID();
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38378185
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил, благодарю! Спасибо большое!
так:
Код: plaintext
1.
BSTR result= ::SysAllocString( L"ляля тополя");	


работает.
а как быть, если у меня внутренний метод возвращает wchar_t* и мне нужно вернуть значение из этого указателя.
Если делаю так:

Код: plaintext
1.
2.
wchar_t* key=ObtainKey(...);
BSTR result= ::SysAllocString(key);	



то на си шарпе получаю null.
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38378224
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ниггадяй,

странно, проверяйте что возвращает ObtainKey()
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
extern "C" __declspec(dllexport) wchar_t *  GetID();

BSTR GetID()
{
	wchar_t* result=    L"ляля тополя";	
	return result;
}



Код: c#
1.
2.
3.
4.
5.
        [DllImport("MyDll.dll")]        
        private static extern IntPtr GetID();
...
	IntPtr p=  GetID();
        string s = Marshal.PtrToStringUni(p);


смотрите, что в р
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38378240
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил, в p адрес, ляля тополя я получаю в си шарпе, но мне нужно вернуть значение, которое возвращает ObtainKey.
Вот оригинальный исходник:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
wchar_t* ObtainKey(const BSTR cname,const BSTR pname)
{
	HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);  
	if(FAILED(hRes))  
	{  
		//cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;  
		return NULL;  
	}  

	if((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))  
	{  
		//cout << "Unable to initialize security: 0x" << std::hex << hRes << endl;  
		//return NULL;  
	}  

	IWbemLocator* pLocator = NULL;  
	if(FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))  
	{  
		//cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;  
		return NULL;  
	}  

	IWbemServices* pService = NULL;  
	if(FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))  
	{  
		pLocator->Release();  
		//cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;  
		return NULL;  
	}  

	IEnumWbemClassObject* pEnumerator = NULL;  
	wchar_t* q=(wchar_t*)malloc(128);
	q[0] = '\0';
	wcscat(q, L"SELECT ");	
	wcscat(q, pname);
	wcscat(q, L" FROM ");
	wcscat(q, cname);

	if(FAILED(hRes = pService->ExecQuery(L"WQL", q, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))  
	{  
		pLocator->Release();  
		pService->Release();  
		//cout << "Unable to retrive desktop monitors: " << std::hex << hRes << endl;  
		return NULL;  
	}  
	wchar_t* result=NULL;
	IWbemClassObject* clsObj = NULL;  
	int numElems;  
	while((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)  
	{  
		if(FAILED(hRes))  
			break;  

		VARIANT vRet;  
		VariantInit(&vRet);  
		if(SUCCEEDED(clsObj->Get(pname, 0, &vRet, NULL, NULL)) && vRet.vt == VT_BSTR)  
		{  
			result = vRet.bstrVal;
			//std::wcout << L"Description: " << vRet.bstrVal << endl;  
			VariantClear(&vRet);  
		}  

		clsObj->Release();  
		if(result != NULL && wcslen(result) > 0)
			break;
	} 

	pEnumerator->Release();  
	pService->Release();  
	pLocator->Release();  

	if(result != NULL)
	{
		wchar_t *end = result + wcslen(result)-1;
		while(*result && isspace(*result))
			*result++ = 0;
		while(isspace(*end))
			*end-- = 0;
	}
	return result;
}



в двух словах, результатом данного метода будет указатель на значение какого-либо реквизита (например,
Код: plaintext
1.
 wchar_t* key=ObtainKey(L"Win32_PhysicalMedia", L"SerialNumber");


вернет серийник харда

метод стабильный, под дебагом проверял, возвращает указатель, значение в консоль выводил.. но когда делаю динамическую библиотеку, чтоб из си шарпа вызывать возникают проблемы.

Код: plaintext
1.
2.
3.
4.
wchar_t* GetID1()
{
	return ObtainKey(L"Win32_PhysicalMedia", L"SerialNumber");
}



Код: c#
1.
2.
        [DllImport("ND.Base.dll", EntryPoint = "GetID1")]
        private static extern IntPtr GetID1();



возвращает 0, такое ощущение, что на подобии как в дотнете, работает сборщик мусора и хлопает его. есть ли какое-то ключевое слово в си++ чтоб указатель не умер после отработки метода?
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38378254
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
прошу извинить, что ввел в заблуждение.

в режиме динамической библиотеке метод ObtainKey не работает(((

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
wchar_t* ObtainKey(const BSTR cname,const BSTR pname)
{
	HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);  
	if(FAILED(hRes))  
	{  
		//cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;  
		return L"Unable to launch COM: 0x";  
	}  

	if((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))  
	{  
		//cout << "Unable to initialize security: 0x" << std::hex << hRes << endl;  
		//return NULL;  
	}  

	IWbemLocator* pLocator = NULL;  
	if(FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))  
	{  
		//cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;  
		return L"Unable to create a WbemLocator:";  
	}  

	IWbemServices* pService = NULL;  
	if(FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))  
	{  
		pLocator->Release();  
		//cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;  
		return L"Unable to connect to \"CIMV2\": ";  
	}  

	IEnumWbemClassObject* pEnumerator = NULL;  
	wchar_t* q=(wchar_t*)malloc(128);
	q[0] = '\0';
	wcscat(q, L"SELECT ");	
	wcscat(q, pname);
	wcscat(q, L" FROM ");
	wcscat(q, cname);

	if(FAILED(hRes = pService->ExecQuery(L"WQL", q, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))  
	{  
		pLocator->Release();  
		pService->Release();  
		//cout << "Unable to retrive desktop monitors: " << std::hex << hRes << endl;  
		return L"Unable to retrive desktop monitors: ";  
	}  
	wchar_t* result=NULL;
	IWbemClassObject* clsObj = NULL;  
	int numElems;  
	while((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)  
	{  
		if(FAILED(hRes))  
			break;  

		VARIANT vRet;  
		VariantInit(&vRet);  
		if(SUCCEEDED(clsObj->Get(pname, 0, &vRet, NULL, NULL)) && vRet.vt == VT_BSTR)  
		{  
			result = vRet.bstrVal;
			//std::wcout << L"Description: " << vRet.bstrVal << endl;  
			VariantClear(&vRet);  
		}  

		clsObj->Release();  
		if(result != NULL && wcslen(result) > 0)
			break;
	} 

	pEnumerator->Release();  
	pService->Release();  
	pLocator->Release();  

	if(result != NULL)
	{
		wchar_t *end = result + wcslen(result)-1;
		while(*result && isspace(*result))
			*result++ = 0;
		while(isspace(*end))
			*end-- = 0;
	}
	return result;
}



получаю текст "Unable to retrive desktop monitors:"

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
if(FAILED(hRes = pService->ExecQuery(L"WQL", q, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))  
	{  
		pLocator->Release();  
		pService->Release();  
		//cout << "Unable to retrive desktop monitors: " << std::hex << hRes << endl;  
		return L"Unable to retrive desktop monitors: ";  
	}  



не фурычит..блин
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38378269
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а точнее не проходит секурити

Код: plaintext
1.
2.
3.
4.
5.
if((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))  
	{  
cout << "Unable to initialize security: 0x" << std::hex << hRes << endl;  
		//return NULL;  
	}  



что не хватает?
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38378315
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
видимо надо поиграться с флагами RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE и т.д
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38378351
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
или со стороны шарпа нужно еще какой-то танец с бубном исполнить? Никто не подскажет, в си++ несилен((
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38378377
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ниггадяй,

WMI в шарпе и без с++ работает
...
Рейтинг: 0 / 0
Получить данные из метода на Си++ в Си#
    #38378379
Ниггадяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил, знаю, но помимо WMI будет код наращиваться, это раз, во вторых скрыть от рефлектора.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Получить данные из метода на Си++ в Си#
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]