Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Получить данные из метода на Си++ в Си# / 15 сообщений из 15, страница 1 из 1
26.08.2013, 15:46
    #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
26.08.2013, 15:48
    #38377562
Ниггадяй
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить данные из метода на Си++ в Си#
метод называется GetID, вверху опечатка (GetID1 - неправильное название)
...
Рейтинг: 0 / 0
26.08.2013, 15:53
    #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
26.08.2013, 15:55
    #38377576
Ниггадяй
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить данные из метода на Си++ в Си#
result=(wchar_t*)malloc(128);
...
Рейтинг: 0 / 0
26.08.2013, 16:35
    #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
26.08.2013, 21:36
    #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
27.08.2013, 10:12
    #38378185
Ниггадяй
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить данные из метода на Си++ в Си#
Изопропил, благодарю! Спасибо большое!
так:
Код: plaintext
1.
BSTR result= ::SysAllocString( L"ляля тополя");	


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

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



то на си шарпе получаю null.
...
Рейтинг: 0 / 0
27.08.2013, 10:34
    #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
27.08.2013, 10:44
    #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
27.08.2013, 10:52
    #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
27.08.2013, 10:58
    #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
27.08.2013, 11:18
    #38378315
Ниггадяй
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить данные из метода на Си++ в Си#
видимо надо поиграться с флагами RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE и т.д
...
Рейтинг: 0 / 0
27.08.2013, 11:40
    #38378351
Ниггадяй
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить данные из метода на Си++ в Си#
или со стороны шарпа нужно еще какой-то танец с бубном исполнить? Никто не подскажет, в си++ несилен((
...
Рейтинг: 0 / 0
27.08.2013, 11:50
    #38378377
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить данные из метода на Си++ в Си#
Ниггадяй,

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


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