通过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?

参考一下微软关于非托管组件的文档。可以先看一下MSDN的文章Consuming Unmanaged DLL Functions.如想在你的.NET应用中找到更多使用非托管组件的资源,可以参考Interoperating with Unmanaged Code.


相关链接: Product Documentation: National Instruments .NET Driver Support

External 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 API

KnowledgeBase 6ZMFG7D9: Enabling NI-TClk Support for an NI Modular Instruments.NET Source Code Wrapper API

附件:





报告日期: 08/19/2015
最近更新: 09/24/2015
文档编号: 70IKG6D9