| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | «  : 22-02-2008 00:16 »  |  | 
 
 проблема в следующем:
 
 на С++ создана (ATL) DLL для использование в C# проекте.
 
 в DLL пока тока одна функция, передаётся указатель на массив чисел INT (координаты X и Y, это полигон) и точка с координатами X,Y. Функция определят лежит ли точка внутри полигона или снаружи.
 
 тест работает нормально, но в многократном вызове этой функции из C#  (раз 50-150 подряд) иногда выскакивает следующая ошибка:
 
 "The server threw an exception."
 
 если у кого есть опыт посдкажите пожалуйста хотябы где начать рыть. С++ тока начал изучать и не хочу отказываться, работает быстрее, темболее есть возможность компилировать в Native code.
 
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Алексей++ 
								глобальный и пушистыйГлобальный модератор    Offline 
								Сообщений: 13
								
								
								
								
								
							 | 
								|  | « Ответ #1 : 22-02-2008 04:11 »  |  | 
 
 1) а покажи пример массива, как ты его заполняешь и передаёшь2) может написать свою функцию ?
 |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | « Ответ #2 : 22-02-2008 13:38 »  |  | 
 
 с удовольствием! вот сама функция в Polygone классе 	static int __fastcall PointInPoly(LONG Px, LONG Py, LONG* Vx, LONG* Vy, LONG n){
 LONG  cn = 0;    // the crossing number counter
 int i = 0;
 // loop through all edges of the polygon
 while(n) {// edge from V[i] to V[i+1]
 if (((Vy[i] <= Py) && (Vy[i+1] > Py))    // an upward crossing
 || ((Vy[i] > Py) && (Vy[i+1] <= Py))) { // a downward crossing
 // compute the actual edge-ray intersect x-coordinate
 float vt = (float)(Py - Vy[i]) / (Vy[i+1] - Vy[i]);
 if (Px < Vx[i] + vt * (Vx[i+1] - Vx[i])) // P.x < intersect
 ++cn;   // a valid crossing of y=P.y right of P.x
 }
 i++;
 n--;
 }
 return (cn&1);    // 0 if even (out), and 1 if odd (in)
 }
 
 |  
						| 
								|  |  
								| « Последнее редактирование: 22-02-2008 15:21 от Алексей1153++ » |  Записан | 
 |  |  | 
	| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | « Ответ #3 : 22-02-2008 13:42 »  |  | 
 
 а это находится в simple ATL объекте math. у которого есть интерфейс
 
 STDMETHODIMP Cmath::PointInPolygon(LONG px, LONG py, LONG* xx, LONG* yy, LONG n, LONG* plResult)
 {
 //      __try
 //    {
 
 *plResult = Polygone::PointInPoly(px, py, xx, yy, n);
 
 //     }
 //       __except (EXCEPTION_EXECUTE_HANDLER)
 //   {
 //   //printf("Exception handler %lX\n", _exception_code());
 //       Sleep(10);
 //   *plResult = -10;
 //}
 
 return S_OK;
 }
 |  
						| 
								|  |  
								| « Последнее редактирование: 22-02-2008 13:53 от bublik478 » |  Записан | 
 |  |  | 
	| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | « Ответ #4 : 22-02-2008 13:43 »  |  | 
 
 сам интерфейс который находится в DLL.idl файле:
 interface Imath : IUnknown{
 [helpstring("method plg_pin")] HRESULT plg_pin([in] LONG px, [in] LONG py, [in] LONG* xx, [in] LONG* yy, [in] LONG n, [out,retval] LONG* plResult);
 };
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | « Ответ #5 : 22-02-2008 13:52 »  |  | 
 
 массив создаётся в С#  а в с++ я передаю указатель на первый член этого массива, тип данных массива и размер массива.из c# вызываю так:
 
 int[] xs = new int[100];
 int[] ys = new int[100];
 
 далее заполняю xs и ys.
 и теперь вызов с++
 
 myDLL.math m = new myDLL.math()
 if(m.PointInPolygon(Px,Py, ref xs[0], ref  ys[0], ys.length))
 {
 // наша точка Px, Py лежит внутри многоугольника!
 }
 
 у многоугольника первая точка и последняя одинаковы! он замкнутый!
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Алексей++ 
								глобальный и пушистыйГлобальный модератор    Offline 
								Сообщений: 13
								
								
								
								
								
							 | 
								|  | « Ответ #6 : 22-02-2008 15:27 »  |  | 
 
 а массив каждый раз содержит разные данные или одни и теже ?
 если разные - при каком содержимом массива происходит вылет  и происходит ли это регклярно ?
 
 (проверить ничего не могу за неимением шарпа )
 |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | « Ответ #7 : 22-02-2008 20:07 »  |  | 
 
 скажем так размерность массива разная бывает, а тим данных один и тотже.
 создаётся первый массив (точки многоугольника) и проверятся около 30-40 точек внутри полигона они или нет, потом следующая серия точек проверяется для следующего полигона и т.д.
 
 и вылетает где самые большие полигоны (массивы) и где чаще всего используется эта функция, но не всегда на одном и томже месте!
 
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | « Ответ #8 : 22-02-2008 20:08 »  |  | 
 
 
 кстати а как лучше передавать данные в С++???
 
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Алексей++ 
								глобальный и пушистыйГлобальный модератор    Offline 
								Сообщений: 13
								
								
								
								
								
							 | 
								|  | « Ответ #9 : 22-02-2008 20:11 »  |  | 
 
 а что означает - передавать данные в c++ ? |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| Алексей++ 
								глобальный и пушистыйГлобальный модератор    Offline 
								Сообщений: 13
								
								
								
								
								
							 | 
								|  | « Ответ #10 : 22-02-2008 20:12 »  |  | 
 
 а запусти в дебаге то - где именно вылетает ? Или в шарпе низя так ? |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| Dimka 
								ДеятельКоманда клуба    Offline 
								Пол:    | 
								|  | « Ответ #11 : 22-02-2008 20:23 »  |  | 
 
 Я бы для отладки добавил бы проверку ассертами Vx и Vy на неравенство NULL до цикла и писал бы в лог значения Vx[ i ], Vy[ i ], Vx[i+1], Vy[i+1]. Хоть видно будет, что в массиве хранится именно то, что нужно. |  
						| 
								|  |  
								|  |  Записан | 
 
 Программировать - значит понимать (К. Нюгард)Невывернутое лучше, чем вправленное (М. Аврелий)
 Многие готовы скорее умереть, чем подумать (Б. Рассел)
 |  |  | 
	| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | « Ответ #12 : 22-02-2008 21:00 »  |  | 
 
 debug сишарпа показывает что при очередном вызове с++ вункции генерируется ошиба как написано в первом сообщении.
 все числа перед передачей в с++ проверяются, они не равны NULL и данные корректны
 |  
						| 
								|  |  
								| « Последнее редактирование: 22-02-2008 21:03 от bublik478 » |  Записан | 
 |  |  | 
	| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | « Ответ #13 : 22-02-2008 21:02 »  |  | 
 
 а что означает - передавать данные в c++ ?
 я имелл виду например как лучше было бы передать массив из c# в с++ и что лучше передавать массив стандартного типа  или например создать структуру в с++ а заполнять её в c# и передавать обратно в с++  |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Алексей++ 
								глобальный и пушистыйГлобальный модератор    Offline 
								Сообщений: 13
								
								
								
								
								
							 | 
								|  | « Ответ #14 : 22-02-2008 21:20 »  |  | 
 
 bublik478, про дебаг... Просто раз уж ты показал исходный код (коли среда тебе это позволяет), то может работает следующее: например ищу я глюк, который известно, когда возникает. В VC6 я могу без точек останова запустить свою программу в дебаге, а когда она отвалится , появляется окно с кнопками - прервать, повторить и ещё чивота там. Жму повторить - оказываюсь на строке ассемблерного кода, где произошла некорректное действие (если повезёт - то и в строке исходника). Открываю стек вызовов , смотрю, откуда перешли сюда, какие там значения переменных были и т.д. Я про это. я имелл виду например как лучше было бы передать массив из c# в с++ и что лучше передавать массив стандартного типа  или например создать структуру в с++ а заполнять её в c# и передавать обратно в с++
 понятия не имею ) Наверное , лучше массив стандартного типа |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | « Ответ #15 : 22-02-2008 22:19 »  |  | 
 
 ok, спасибо за совет, попробуем дебагить с++. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Алексей++ 
								глобальный и пушистыйГлобальный модератор    Offline 
								Сообщений: 13
								
								
								
								
								
							 | 
								|  | « Ответ #16 : 22-02-2008 22:24 »  |  | 
 
 да это не совет, а предположение ) |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| Dimka 
								ДеятельКоманда клуба    Offline 
								Пол:    | 
								|  | « Ответ #17 : 23-02-2008 07:28 »  |  | 
 
 myDLL.math m = new myDLL.math() Это создание COM-объекта, как я понимаю? Если мне память не изменяет, COM-объекты имеют интерфейс IDisposable. Сборщик мусора, конечно, всё подберёт, но авось поможет явный вызов удаления COM-объекта. Тогда надо писать: myDLL.math m = new myDLL.math();...
 m.Dispose();
 или, используя синтаксическую конструкцию: using(myDLL.math m = new myDLL.math()){
 ...
 }
 Что одно и то же. Впрочем, это всё гадание на кофейной гуще и метод тыка. |  
						| 
								|  |  
								| « Последнее редактирование: 23-02-2008 07:30 от dimka » |  Записан | 
 
 Программировать - значит понимать (К. Нюгард)Невывернутое лучше, чем вправленное (М. Аврелий)
 Многие готовы скорее умереть, чем подумать (Б. Рассел)
 |  |  | 
	| 
			| 
					
						| bublik478 
								Гость
 | 
								|  | « Ответ #18 : 23-02-2008 22:20 »  |  | 
 
 dimka, 
 чтоб использовать метод Dispose
 или запись в виде
 using()
 {
 
 }
 
 где сразу после выхода за фигурные скобки вызывается Dispose.  то надо чтоб объект поддерживал интерфейс IDisposable!
 
 но моя dll этого не поддерживатеб и это я нигде не прописывал!
 
 а вот чтоб мгновенно освободить занимаемую com объектом память, можно пользоваться следующим:
 
 System.Runtime.InteropServices.Marshal.ReleaseComObject(наш сом объект);
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	|  |