Я использовал код, который вы разместили вместе с последней версией библиотеки, и он отлично работает для меня. Одна вещь, которую вы могли бы рассмотреть - это оборачивать как C ++ / CLI вместо использования P / Invoke, но это уже другая тема.
Я работаю в предположении, что вы используете Visual Studio 2010 (да ладно, нужно с чего-то начинать :-)).
Одна вещь, которая явно не в порядке:
Native:
extern "C" __declspec (dllexport) void __stdcall convertGeocentricToMGRS (const double x, const double y, const double z, char * & mgrsString, Precision :: Enum & precision)
и C #:
[DllImport ( "CoordinateConversionWrapper.dll")]
private static extern void convertGeocentricToMGRS (double x, double y, double z, ref char [] mgrsString, Precision precision);
Do:
extern "C"__declspec(dllexport) void __stdcall convertGeocentricToMGRS(const double x, const double y, const double z, char** mgrsString, Precision::Enum& precision)
{
MSP::CCS::CoordinateSystemParameters geocentricParameters(MSP::CCS::CoordinateType::geocentric);
MSP::CCS::CoordinateSystemParameters mgrsParameters(MSP::CCS::CoordinateType::militaryGridReferenceSystem);
MSP::CCS::CoordinateConversionService ccs( "WGE", &geocentricParameters, "WGE", &mgrsParameters );
MSP::CCS::Accuracy sourceAccuracy;
MSP::CCS::Accuracy targetAccuracy;
MSP::CCS::CartesianCoordinates sourceCoordinates(MSP::CCS::CoordinateType::geocentric, x, y, z);
MSP::CCS::MGRSorUSNGCoordinates targetCoordinates;
ccs.convertSourceToTarget( &sourceCoordinates, &sourceAccuracy, targetCoordinates, targetAccuracy );
int nMGRSLen = strlen( targetCoordinates.MGRSString() );
::CoTaskMemFree(*mgrsString);
*mgrsString = (char *)::CoTaskMemAlloc(nMGRSLen + 1);
strcpy( *mgrsString, targetCoordinates.MGRSString() );
precision = targetCoordinates.precision();
}
Обратите внимание, что символ передается как указатель на указатель, и что используются CoTaskMemFree / CoTaskMemAlloc / strcpy (включая Objbase.h для CoTaskMemAlloc)
А в коде C # вы можете:
[DllImport("MSPGeotransTest.dll", CharSet= CharSet.Ansi))]
public static extern void convertGeocentricToMGRS(double x, double y, double z, ref string mgrsString, ref PrecisionEnum precision);
где:
public enum PrecisionEnum : uint
{
degree = 0,
tenMinute = 1,
minute = 2,
tenSecond = 3,
second = 4,
tenthOfSecond = 5,
hundrethOfSecond = 6,
thousandthOfSecond = 7,
tenThousandthOfSecond = 8
}
Возможно, существуют другие возможности сделать это ...
Некоторые другие полезные вещи:
Для возможности отладки убедитесь, что:
В меню Инструменты> Параметры> Отладка> Общие флажок «Включить только мой код» не установлен.
В Project> Properties> вкладка Debug установлен флажок «Включить отладку неуправляемого кода».
Поместите точку останова в метод C #, и когда точка останова будет достигнута, вы можете перейти в F11 и достичь кода C ++ ...
Я скомпилировал C ++ Dll, выбрав «Использовать многобайтовый набор символов» (Свойства конфигурации \ Общие \ Набор символов)
Также может показаться, что конструктор CoordinateConversionService выдает исключение CoordinateConversionException, если он не может загрузить файлы конфигурации (при их поиске он выглядит как путь, который можно настроить через переменную среды с именем MSPCCS_DATA, и если переменная среды не определена он ищет их в ../../data/ относительно пути exe).
Вероятно, в методах-оболочках C ++ может быть, вы хотите перехватить любые исключения, которые могут быть вызваны вызванными методами, и вернуть код ошибки ... Т.е. другие ситуации, которые вызывают исключения, вызваны неправильными входными координатами и т. д.
Как я уже сказал, у меня есть рабочий пример, поэтому, если хотите, я могу отправить его вам ...