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(наш сом объект);
|
|
|
Записан
|
|
|
|
|