English 中文(简体)
Geotrans p/invoke Packper Null Reference Exception
原标题:GeoTrans p/invoke wrapper NullReferenceException

我试图揭露方法,我需要从GeoTrans c++图书馆打电话,但正在处理。 任何帮助都是巨大的。

我有以下的C++文件,即一毫 running不成堆,不成堆。

#include <iostream>

#include "CoordinateConversionService.h"
#include "CoordinateSystemParameters.h"
#include "GeodeticParameters.h"
#include "CoordinateTuple.h"
#include "GeodeticCoordinates.h"
#include "CartesianCoordinates.h"
#include "Accuracy.h"
#include "MGRSorUSNGCoordinates.h"
#include "UTMParameters.h"
#include "UTMCoordinates.h"
#include "CoordinateType.h"
#include "HeightType.h"
#include "CoordinateConversionException.h"

using MSP::CCS::Precision;

int main(int argc, char **argv){}

extern "C"__declspec(dllexport) void __stdcall convertGeodeticToGeocentric(const double lat,const double lon, const double height, double& x, double& y, double& z)
{       
        MSP::CCS::CoordinateSystemParameters geocentricParameters(MSP::CCS::CoordinateType::geocentric);
        MSP::CCS::CoordinateConversionService ccs( "WGE", &geodeticParameters, "WGE", &geocentricParameters );
        MSP::CCS::Accuracy sourceAccuracy;
        MSP::CCS::Accuracy targetAccuracy;
        MSP::CCS::GeodeticCoordinates sourceCoordinates(MSP::CCS::CoordinateType::geodetic, lon, lat, height);
        MSP::CCS::CartesianCoordinates targetCoordinates(MSP::CCS::CoordinateType::geocentric);
        ccs.convertSourceToTarget( &sourceCoordinates, &sourceAccuracy, targetCoordinates, targetAccuracy );
        x = targetCoordinates.x();
        y = targetCoordinates.y();
        z = targetCoordinates.z();
}

extern "C"__declspec(dllexport) void __stdcall convertGeocentricToGeodetic(const double x, const double y, const double z, double& lat,double& lon, double& height)
{
        MSP::CCS::CoordinateSystemParameters geocentricParameters(MSP::CCS::CoordinateType::geocentric);
        MSP::CCS::GeodeticParameters geodeticParameters(MSP::CCS::CoordinateType::geodetic, MSP::CCS::HeightType::ellipsoidHeight);
        MSP::CCS::CoordinateConversionService ccs( "WGE", &geocentricParameters, "WGE", &geodeticParameters );
        MSP::CCS::Accuracy sourceAccuracy;
        MSP::CCS::Accuracy targetAccuracy;
        MSP::CCS::CartesianCoordinates sourceCoordinates(MSP::CCS::CoordinateType::geocentric, x, y, z);
        MSP::CCS::GeodeticCoordinates targetCoordinates;
        ccs.convertSourceToTarget( &sourceCoordinates, &sourceAccuracy, targetCoordinates, targetAccuracy );
        lat = targetCoordinates.latitude();
        lon = targetCoordinates.longitude();
        height = targetCoordinates.height();
}

extern "C"__declspec(dllexport) void __stdcall convertGeocentricToUTM(const double x, const double y, const double z, long& zone, char& hemisphere, double& easting, double& northing)
{
        MSP::CCS::CoordinateSystemParameters geocentricParameters(MSP::CCS::CoordinateType::geocentric);
        MSP::CCS::UTMParameters utmParameters(MSP::CCS::CoordinateType::universalTransverseMercator, 1, 0);
        MSP::CCS::CoordinateConversionService ccs( "WGE", &geocentricParameters, "WGE", &utmParameters );
        MSP::CCS::Accuracy sourceAccuracy;
        MSP::CCS::Accuracy targetAccuracy;
        MSP::CCS::CartesianCoordinates sourceCoordinates(MSP::CCS::CoordinateType::geocentric, x, y, z);
        MSP::CCS::UTMCoordinates targetCoordinates;
        ccs.convertSourceToTarget( &sourceCoordinates, &sourceAccuracy, targetCoordinates, targetAccuracy );
        zone = targetCoordinates.zone();
        hemisphere = targetCoordinates.hemisphere();
        easting = targetCoordinates.easting();
        northing = targetCoordinates.northing();
}

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 );
        mgrsString = targetCoordinates.MGRSString();
        precision = targetCoordinates.precision();
}

然后,我有以下的p/invoke电话。

[DllImport("CoordinateConversionWrapper.dll")]
private static extern void convertGeodeticToGeocentric(double lat, double lon, double height, ref double x, ref double y, ref double z);

[DllImport("CoordinateConversionWrapper.dll")]
private static extern void convertGeocentricToMGRS(double x, double y, double z, ref char[] mgrsString, Precision precision);

采用上述p/invoke方法,可产生一种新观念。 这个问题似乎属于++代码本身,但并不是一个P++专家Im无法确定问题是什么。

请帮助!

问题回答

我建议修改你的法典。 您能够能够在您的C#项目(Debug tab)的环境下制定不受管理的守则。

Please post also the calling code.

Remark: string output parameters for p/invoke are typically done with the StringBuilder class.

[EDIT] There is a problem with the string output - who provides the storage for the string and who is freeing it (if needed)? The only useful solution is to pass the storage (as char*) and the length of it into the C++ function. Use StringBuilder on the C# side as mentioned.

I used the code you posted together with the latest version of the library and it works fine for me. One thing you might consider is wrapping as C++/CLI instead of using P/Invoke but this is another topic.

I am working under the assumption you are using Visual Studio 2010 (oh well one has to start somewhere :-) ).

明显没有做的事情是:

<>0>

extern “C”__declspec(dllexport) void __stdtation TransformationGeocentric ToMGRS (const Double x, const Double y, const Double z, char*&毫克rsString,精密:Enum&精密)

<>strong>and 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();
}

请注意,这些果园被作为点子通过,而CTaskMemAlloc/strcpy则被使用(CTaskMem Alloc,include Objbase.h)。

在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
    }

或许还有其他可能这样做......

其他一些有益的事情:

• 确保:

在“工具”中,“选择”和“选择”,一般说来,“可以理解的《我法》”没有受到控制。

在“项目”中,对“不动产”进行了检查。

在“C#”方法中以及当达到“打破点”时,可以进入F11,达到C++代码......。

我汇编了C++。 Dll, 选择“Use Multi-Byte nature Set”(不动产总分类)

此外,如果无法装上配置文件,那么“协调服务”建筑商似乎会扔下一种协调的转变观念(查询文件似乎通过一个称为“MSPCCS_DATA”的环境变数加以配置,如果环境变数没有界定,则会从外部途径看。

也许,在C++总结方法中,你可能希望破获任何可以被所谓的方法所推翻的例外,并退回错误代码...... I.e. 引起例外的其他情况是由于输入坐标无效等等。

正如我说过的那样,如果你希望我能向你转达,我就有一个工作榜样。





相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签