管理 C++ C# 中的 Garmin API
我想在VB.Net Compact Framework项目中调用Garmin API。 API 采用 C++ 语言,因此我正在制作一个 C# dll 项目作为 API dll 和 VB.NET 之间的中间方式。我在执行代码时遇到一些问题,因为它在 QueCreatePoint
调用中抛出 NotSupportedException
(我认为是错误的参数类型)。下面是 C++ API 代码和我的 C# 工作。
C++ 函数原型和 C# P/Invoke 调用:
QueAPIExport QueErrT16 QueCreatePoint( const QuePointType* point, QuePointHandle* handle );
QueAPIExport QueErrT16 QueClosePoint( QuePointHandle point );
[DllImport("QueAPI.dll")]
private static extern QueErrT16 QueCreatePoint(ref QuePointType point, ref uint handle);
[DllImport("QueAPI.dll")]
private static extern QueErrT16 QueRouteToPoint(uint point);
QueErrT16:
typedef uint16 QueErrT16; enum { ... }
public enum QueErrT16 : ushort { ... }
QuePointType:
typedef struct
{
char id[25];
QueSymbolT16 smbl;
QuePositionDataType posn;
} QuePointType;
public struct QuePointType
{
public string id;
public QueSymbolT16 smbl;
public QuePositionDataType posn;
}
QueSymbolT16:
typedef uint16 QueSymbolT16; enum { ... }
public enum QueSymbolT16 : ushort { ... }
QuePositionDataType:
typedef struct
{
sint32 lat;
sint32 lon;
float altMSL;
} QuePositionDataType;
public struct QuePositionDataType
{
public int lat;
public int lon;
public float altMSL;
}
QuePointHandle:
typedef uint32 QuePointHandle;
在 C# 中,我将其作为 uint
var 进行管理。
这是我当前调用所有这些的 C# 函数:
public static QueErrT16 GarminNavigateToCoordinates(double latitude , double longitude)
{
QueErrT16 err = new QueErrT16();
// Open API
err = QueAPIOpen();
if(err != QueErrT16.queErrNone)
{
return err;
}
// Create position
QuePositionDataType position = new QuePositionDataType();
position.lat = GradosDecimalesASemicirculos(latitude);
position.lon = GradosDecimalesASemicirculos(longitude);
// Create point
QuePointType point = new QuePointType();
point.posn = position;
// Crete point handle
uint hPoint = new uint();
err = QueCreatePoint(ref point, ref hPoint); // HERE i got a NotSupportedException
if (err == QueErrT16.queErrNone)
{
err = QueRouteToPoint(hPoint);
}
// Close API
QueAPIClose();
return err;
}
I want to call Garmin API in VB.Net Compact Framework project. The API is in C++, so I'm making a C# dll project as intermediate way between API dll and VB.NET. I have some problems while executing my code because it throws a NotSupportedException
(bad arguments type, I think) in the QueCreatePoint
call. Below is the C++ API code and my C# work.
C++ Functions prototype and C# P/Invoke Calls:
QueAPIExport QueErrT16 QueCreatePoint( const QuePointType* point, QuePointHandle* handle );
QueAPIExport QueErrT16 QueClosePoint( QuePointHandle point );
[DllImport("QueAPI.dll")]
private static extern QueErrT16 QueCreatePoint(ref QuePointType point, ref uint handle);
[DllImport("QueAPI.dll")]
private static extern QueErrT16 QueRouteToPoint(uint point);
QueErrT16:
typedef uint16 QueErrT16; enum { ... }
public enum QueErrT16 : ushort { ... }
QuePointType:
typedef struct
{
char id[25];
QueSymbolT16 smbl;
QuePositionDataType posn;
} QuePointType;
public struct QuePointType
{
public string id;
public QueSymbolT16 smbl;
public QuePositionDataType posn;
}
QueSymbolT16:
typedef uint16 QueSymbolT16; enum { ... }
public enum QueSymbolT16 : ushort { ... }
QuePositionDataType:
typedef struct
{
sint32 lat;
sint32 lon;
float altMSL;
} QuePositionDataType;
public struct QuePositionDataType
{
public int lat;
public int lon;
public float altMSL;
}
QuePointHandle:
typedef uint32 QuePointHandle;
In C# I manage it as a uint
var.
And this is my current C# function to call all this:
public static QueErrT16 GarminNavigateToCoordinates(double latitude , double longitude)
{
QueErrT16 err = new QueErrT16();
// Open API
err = QueAPIOpen();
if(err != QueErrT16.queErrNone)
{
return err;
}
// Create position
QuePositionDataType position = new QuePositionDataType();
position.lat = GradosDecimalesASemicirculos(latitude);
position.lon = GradosDecimalesASemicirculos(longitude);
// Create point
QuePointType point = new QuePointType();
point.posn = position;
// Crete point handle
uint hPoint = new uint();
err = QueCreatePoint(ref point, ref hPoint); // HERE i got a NotSupportedException
if (err == QueErrT16.queErrNone)
{
err = QueRouteToPoint(hPoint);
}
// Close API
QueAPIClose();
return err;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您应该能够直接从 VB 对这些使用 pInvoke,而无需 C# 包装器(或 C++ 包装器)。声明应该是这样的:
我认为开头的 C 声明是 QueClosePoint 而 pInvoke 声明是 QueRouteToPoint 是有原因的。根据对齐/包装问题以及各种物品的使用方式,可能需要进行一些调整。
You should be able to use pInvoke on these directly from VB without the C# wrapper (or the C++ wrapper). The declarations should be something along these lines:
I assume that there is a reason that the C declare at the beginning is QueClosePoint and the pInvoke declare is QueRouteToPoint. Some tweaking may be necessary with this depending on alignment/packing issues and how the various items are used.
您始终可以创建一个 CPP/CLI 项目,用托管 API 包装本机 API。通常,以这种方式编写托管包装器比使用 DllImprt 要简单得多。
you could always create a CPP/CLI project that will wrap the native API with a managed API. Usually it's much simpler to write a managed wrapper this way instead of using DllImprt.