通过NI Native.NET API访问驱动中还未开放的C API函数
主要软件: Measurement Studio>>Enterprise Edition (Full Development System)
主要软件版本: 2015
主要软件修正版本: N/A
次要软件: Driver Software>>NI-RFSA, Driver Software>>NI-RFSG, Driver Software>>NI-DCPower, Driver Software>>NI-DMM, Driver Software>>NI-SCOPE, Driver Software>>NI-SWITCH
问题: 我正在使用NI native.NET API 写一个控制NI硬件的应用,NI硬件的驱动更新了但.NET API却没有更新,那这样的话我就不能使用驱动中的新的函数。那么我如何在.Net中去使用这些函数呢?
解答: 有时一个新的NI驱动发布了,但是新的.NET API可能没有及时发布。不过,所有的C语言API都是随着NI驱动的发布而更新的。因为C语言API是最新的,因此你可以将C语言的API封装成.NET可以使用的类型。微软.NET框架提供了一种被称为platform invoke (P/Invoke )的机制使非托管的模块可以在.NET的应用中使用。
下面的单元就是介绍如何创建一个P/Invoke封装以及如何在应用中将其使用。下文是以NI-SCOPE的驱动为例,实际也适用于其他驱动。
通过静态P/Invoke的方法获取C语言API函数
1.决定哪些函数你需要获取,然后在驱动的C语言API头文件中找到它们(比如niScope.h)的声明。函数声明的一般看起来与下面示例类似:
ViStatus _VI_FUNC niScope_ConfigureHorizontalTiming (ViSession vi,
ViReal64 minSampleRate,
ViInt32 minNumPts,
ViReal64 refPosition,
ViInt32 numRecords,
ViBoolean enforceRealtime);
2.定义一个静态的封装类,在其中你将定义那些你希望从C语言API中获取的静态函数。可以如下定义:
internal static class ScopePInvokeMethods
{
}
3.在你刚刚创建的静态类中为每一个你希望获取的函数定义静态函数,然后对于每一个函数都需要构建一个DllImport属性并将它连接至函数所对应的C语言API函数。对于先前给出的niScope_ConfigureHorizontalTiming函数,其构建如下所示:
internal static class ScopePInvokeMethods
{
DllImport( "niScope_32.dll",
EntryPoint = "niScope_ConfigureHorizontalTiming", CallingConvention = CallingConvention.StdCall )]
public static extern int ConfigureHorizontalTiming32(
HandleRef instrumentHandle, double minSampleRate, int minNumPoints, double refPosition, int numRecords, bool enforceRealtime );
}
注意:你可以使用Measurement Studio NI Instrument Driver选项的模板来生成静态P/Invoke函数。关于此想了解更多信息,请参考
How Can I Create a .NET Wrapper for My Instrument Driver?
使用静态P/Invoke函数:
你可以通过调用在静态封装类中的静态函数,使用你自己创建的P/Invoke函数。下面就是调用封装好的32位niScope_ConfigureHorizontalTiming的例子,其对应的.NET API函数是ConfigureTiming (i.e., NIScope.Timing.ConfigureTiming):
// The following is within the scope of some method. double sampleRateMin = 10000000.0; double referencePosition = 50.0; int recordLengthMin = 1000; int numberOfRecords = 1; bool enforceRealtime = true; var sessionHandle = new HandleRef( this._scopeSession,
this._scopeSession.DangerousGetInstrumentHandle( ));
// This does the same thing as this._scopeSession.Timing.ConfigureTiming( // sampleRateMin, recordLengthMin, referencePosition, numberOfRecords, // enforceRealTime ) for a 32-bit application. ScopePInvokeMethods.ConfigureHorizontalTiming32( sessionHandle,
sampleRateMin, recordLengthMin, referencePosition, numberOfRecords, enforceRealTime );
注意:为了使用HandleRef,必须在源代码中添加对System.Runtime.InteropServices的使用。
注意:想了解更多关于如何使用DangerousGetInstrumentHandle函数的信息,请参考<Driver> .NET API Help中的<Driver>.DangerousGetInstrumentHandle函数主题,这里<Driver>是对应的NI驱动的名字。关于HandleRef 结构可以参考MSDN获取更多信息。回顾本文章将会帮助你在使用C语言驱动的句柄时做出正确的决定,特别是在考虑非托管的句柄生命周期的时候。
评论:在.NET应用中封装和使用非托管模块时要特别谨慎。NI建议可以从使用Measurement Studio .NET仪器驱动向导开始,它可以用它的函数面板(.fp)为驱动生成P/Invoke类。如想了解更多信息,请参考How Can I Create a .NET Wrapper for My Instrument Driver?
相关链接: Product Documentation: National Instruments .NET Driver SupportExternal Link: Consuming Unmanaged DLL Functions (MSDN)External Link: Interoperating with Unmanaged Code (MSDN)External Link: HandleRef Structure (System.Runtime.InteropServices) (MSDN)KnowledgeBase 4DPDIEXU: How Can I Create a .NET Wrapper for My Instrument Driver?KnowledgeBase 6ZKGR0D9: Accessing Modular Instruments Driver Attributes through an NI Native .NET APIKnowledgeBase 6ZMFG7D9: Enabling NI-TClk Support for an NI Modular Instruments.NET Source Code Wrapper API
附件:
报告日期: 08/19/2015
最近更新: 09/24/2015
文档编号: 70IKG6D9
Other Support Options
Ask the NI Community
Collaborate with other users in our discussion forums
Request Support from an Engineer
A valid service agreement may be required, and support options vary by country.