Blittable构造从C#到C ++
我正在重写我公司的库代码的过度工程和不可维护的块,这些代码在C#和C ++之间进行接口。 我已经开始研究P / Invoke,但是看起来好像没有什么可访问的帮助。
我们将包含各种参数和设置的结构传递给非托管代码,因此我们正在定义相同的结构。 我们不需要在C ++端更改任何这些参数,但我们需要在P / Invoked函数返回后访问它们。
我的问题是:
作为参考,这是我迄今为止编写的一对结构:
C ++
/**
Struct used for marshalling Scan parameters from managed to unmanaged code.
*/
struct ScanParameters
{
LPSTR deviceID;
LPSTR spdClock;
LPSTR spdStartTrigger;
double spinRpm;
double startRadius;
double endRadius;
double trackSpacing;
UINT64 numTracks;
UINT32 nominalSampleCount;
double gainLimit;
double sampleRate;
double scanHeight;
LPWSTR qmoPath; //includes filename
LPWSTR qzpPath; //includes filename
};
C#
/// <summary>
/// Struct used for marshalling scan parameters between managed and unmanaged code.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ScanParameters
{
[MarshalAs(UnmanagedType.LPStr)]
public string deviceID;
[MarshalAs(UnmanagedType.LPStr)]
public string spdClock;
[MarshalAs(UnmanagedType.LPStr)]
public string spdStartTrigger;
public Double spinRpm;
public Double startRadius;
public Double endRadius;
public Double trackSpacing;
public UInt64 numTracks;
public UInt32 nominalSampleCount;
public Double gainLimit;
public Double sampleRate;
public Double scanHeight;
[MarshalAs(UnmanagedType.LPWStr)]
public string qmoPath;
[MarshalAs(UnmanagedType.LPWStr)]
public string qzpPath;
}
blittable类型是一种在托管代码和非托管代码之间具有共同表示的类型,因此可以在它们之间很少或没有问题地传递,例如byte,int32等。
非blittable类型没有共同的表示形式,例如System.Array,System.String,System.Boolean等。
通过为非blittable类型指定MarshalAs属性,您可以告诉编组人员应将其转换为什么。 有关更多信息,请参阅关于Blittable和Non-Blittable类型的文章
1 - 传递字符串的最佳方式是什么? 有些是短的(设备ID可以由我们设置),有些是文件路径(可能包含亚洲字符)
通常推荐使用StringBuilder作为最简单的使用方式,但我经常使用普通字节数组。
2 - 我应该将一个IntPtr传递给C#结构,还是应该让Marshaller通过将结构类型放入函数签名来处理它?
如果该方法需要一个指针,然后传递一个IntPtr,尽管在很多情况下你可能会得到一个ref,这取决于它将被用于什么。 如果它需要在相同的地方呆很长时间,那么我会用Marshal手动分配内存并传递生成的IntPtr。
3 - 我是否应该担心任何非指针数据类型,如bool或枚举(在其他相关结构中)? 我们将治疗警告设置为C ++中的错误标志,因此我们不能使用微软扩展来枚举来强制数据类型。
一旦你用正确的编组属性设置了一切,我不明白为什么你需要担心。 如果有疑问放入属性中,如果该结构只能被托管代码使用,则该属性将不会被使用。
4 - P / Invoke实际上是要走的路吗? 有一些关于Implicit P / Invoke的微软文档说,它是更安全和更高效的。
无法对此发表评论,你在那里进入Visual C ++领域。
链接地址: http://www.djcxy.com/p/66597.html