我为National Instruments SPI设备提供了一个包装器-它在.Net Core中可完美运行。我想包装一个UI包装,因此将同一包装器推入.Net Framework。在那里,大多数调用都能正常工作,但是失败了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。工程。
我还制作了一个.Net标准包装器项目,并且在两个应用程序中都引用了它。相同的包装dll在.Net核心项目中有效,但在Framework中无效!这里发生了什么?似乎.Net Core在如何处理Interop方面有一些额外的启发。问题是如何/为什么? .Net Core Winforms alpha插件不够稳定或功能不足,无法使用,我真的需要在标准.Net Framework项目中工作。
它可用于配置,设置DIO等,但是当我们尝试进行操作时会崩溃
NI845x.ni845xSpiWriteRead(handle, SPIHandle, (uint)B.Length, B, ref ReadSize, ref ReadMsg);
有人对如何使其正常工作或如何解决问题有任何好的想法吗?谢谢!
以下签名:
public class NI845x { public const byte kNi845x33Volts = 33; // 3.3V public const byte kNi845x25Volts = 25; // 2.5V public const byte kNi845x18Volts = 18; // 1.8V public const byte kNi845x15Volts = 15; // 1.5V public const byte kNi845x12Volts = 12; // 1.2V public const byte kNi845xSpiClockPolarityIdleLow = 0;// Idle Low public const byte kNi845xSpiClockPolarityIdleHigh = 1; // Idle High public const byte kNi845xSpiClockPhaseFirstEdge = 0; // First Edge public const byte kNi845xSpiClockPhaseSecondEdge = 1; // Second Edge [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xFindDevice(StringBuilder FirstDevice, ref ulong FindDeviceHandle, ref UInt32 NumberFound); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xSpiWriteRead(ulong DeviceHandle, ulong ConfigurationHandle, UInt32 WriteSize, byte[] WriteData, ref UInt32 ReadSize, ref byte[] ReadData); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xOpen(StringBuilder ResourceName, ref ulong DeviceHandle); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xSetIoVoltageLevel(ulong DeviceHandle, byte VoltageLevel); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xSpiConfigurationOpen(ref ulong SPIHandle); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xSpiConfigurationSetChipSelect(ulong SPIHandle, UInt32 ChipSelect); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xSpiConfigurationSetClockRate(ulong SPIHandle, UInt16 ClockRate); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xSpiConfigurationSetClockPolarity(ulong SPIHandle, Int32 ClockPolarity); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xSpiConfigurationSetClockPhase(ulong SPIHandle, Int32 ClockPhase); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xSpiConfigurationClose(ulong DeviceHandle); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xClose(ulong DeviceHandle); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xDioWriteLine(ulong DeviceHandle, byte PortNumber, byte LineNumber, Int32 WriteData); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xDioSetPortLineDirectionMap(ulong DeviceHandle, byte PortNumber, byte Map); [DllImport("Ni845x.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Int32 ni845xSetTimeout(ulong DeviceHandle, UInt32 Timeout);
这里是NI的.h文件:
#ifndef __Ni845x_HEADER__ #define __Ni845x_HEADER__ #ifdef __cplusplus extern "C" { #endif #if defined(WIN32) #define NI845X_FUNC __stdcall #elif defined(WIN64) #define NI845X_FUNC __fastcall #elif defined(macosxU) #define NI845X_FUNC #endif #if (defined(WIN32) || defined(WIN64)) #if defined(kExportSymbols) #define kNI845XExport #else #define kNI845XExport #endif #elif defined (macosxU) #if defined(kExportSymbols) #if ( __GNUC__ >= 4 ) #define kNI845XExport __attribute__((visibility("default"))) #else #define kNI845XExport __attribute__ ((section ("__TEXT,__export"))) #endif #else #define kNI845XExport #endif #endif #ifdef _CVI_ #pragma EnableLibraryRuntimeChecking #endif #ifndef _NI_int8_DEFINED_ #define _NI_int8_DEFINED_ typedef char int8; #endif #ifndef _NI_uInt8_DEFINED_ #define _NI_uInt8_DEFINED_ typedef unsigned char uInt8; #endif #ifndef _NI_int16_DEFINED_ #define _NI_int16_DEFINED_ typedef short int16; #endif #ifndef _NI_uInt16_DEFINED_ #define _NI_uInt16_DEFINED_ typedef unsigned short uInt16; #endif #ifndef _NI_int32_DEFINED_ #define _NI_int32_DEFINED_ typedef long int32; #endif #ifndef _NI_uInt32_DEFINED_ #define _NI_uInt32_DEFINED_ typedef unsigned long uInt32; #endif #if defined(WIN64) typedef unsigned long long NiHandle; #elif defined(WIN32) typedef unsigned long NiHandle; #endif typedef struct { uInt32 dimSize; uInt8 elt[1]; } Array1DU8_t; typedef Array1DU8_t **Array1DU8Handle_t; #define kNi845xWarningClockRateCoerced 301700 #define kNi845xWarningSpiSampleDataIgnored 301701 #define kNi845xWarningUnknown 301719 #define kNi845xErrorNoError 0 #define kNi845xErrorInsufficientMemory -301700 #define kNi845xErrorInvalidResourceName -301701 #define kNi845xErrorInvalidClockRate -301702 #define kNi845xErrorTooManyScriptReads -301703 #define kNi845xErrorInvalidScriptReadIndex -301704 #define kNi845xErrorInvalidScriptReference -301705 #define kNi845xErrorInvalidDeviceId -301706 #define kNi845xErrorConnectionLost -301707 #define kNi845xErrorTimeout -301708 #define kNi845xErrorInternal -301709 #define kNi845xErrorInvalidConfigurationReference -301710 #define kNi845xErrorTooManyConfigurations -301711 #define kNi845xErrorInvalidActiveProperty -301712 #define kNi845xErrorInvalidParameter -301713 #define kNi845xErrorResourceBusy -301714 #define kNi845xErrorInvalidMasterCode -301715 #define kNi845xErrorMasterCodeAck -301716 #define kNi845xErrorOverCurrentError -301718 #define kNi845xErrorSpiStreamingModeNotSupported -301780 #define kNi845xErrorI2cSlaveModeNotSupported -301781 #define kNi845xErrorInvalidI2cSlaveEventResponse -301782 #define kNi845xErrorI2cSlaveEventPending -301783 #define kNi845xErrorUnknown -301719 //===================================== // // General Errors from the device // //===================================== #define kNi845xErrorBadOpcode -301720 #define kNi845xErrorUnknownStatus -301721 #define kNi845xErrorProtocolViolation -301722 #define kNi845xErrorInvalidScript -301723 #define kNi845xErrorInvalidFirmware -301724 #define kNi845xErrorIncompatibleFirmware -301725 //===================================== // // SPI Errors from the device // //===================================== #define kNi845xErrorMasterWriteCollision -301730 #define kNi845xErrorInvalidSpiPortNumber -301732 #define kNi845xErrorInvalidCsPortNumber -301733 #define kNi845xErrorInvalidChipSelect -301734 #define kNi845xErrorInvalidBitsPerSample -301735 //===================================== // // I2C Errors from the device // //===================================== #define kNi845xErrorMasterBusFreeTimeout -301740 #define kNi845xErrorMasterCodeArbLost -301741 #define kNi845xErrorMasterAddressNotAcknowledged -301742 #define kNi845xErrorMasterDataNotAcknowledged -301743 #define kNi845xErrorMasterAddressArbitrationLost -301744 #define kNi845xErrorMasterDataArbitrationLost -301745 #define kNi845xErrorInvalidI2CPortNumber -301746 //===================================== // // DIO Errors from the device // //===================================== #define kNi845xErrorInvalidDioPortNumber -301750 #define kNi845xErrorInvalidDioLineNumber -301751 //===================================== // // SPI Streaming Errors from the device // //===================================== #define kNi845xErrorInStreamingMode -301717 #define kNi845xErrorNotInStreamingMode -301760 //===================================== // // SPI Function Arguments // //===================================== #define kNi845xSpiClockPolarityIdleLow 0 // Idle Low #define kNi845xSpiClockPolarityIdleHigh 1 // Idle High #define kNi845xSpiClockPhaseFirstEdge 0 // First Edge #define kNi845xSpiClockPhaseSecondEdge 1 // Second Edge //===================================== // // DIO Function Arguments // //===================================== #define kNi845xDioInput 0 // DIO Direction Input #define kNi845xDioOutput 1 // DIO Direction Output #define kNi845xDioLogicLow 0 // DIO Level Low #define kNi845xDioLogicHigh 1 // DIO Level High //===================================== // // Generic Function Arguments // //===================================== #define kNi845xOpenDrain 0 // Open Drain #define kNi845xPushPull 1 // Push Pull #define kNi845x33Volts 33 // 3.3V #define kNi845x25Volts 25 // 2.5V #define kNi845x18Volts 18 // 1.8V #define kNi845x15Volts 15 // 1.5V #define kNi845x12Volts 12 // 1.2V //These defines are deprecated and the 845x Driver Type and IO Voltage Level //should be used instead #define kNi845xOpenDrain 0 // Open-Drain #define kNi845xPushPull33Volts 1 // 3.3V Push-Pull kNI845XExport int32 NI845X_FUNC ni845xFindDevice ( char * FirstDevice, NiHandle * FindDeviceHandle, uInt32 * NumberFound ); kNI845XExport int32 NI845X_FUNC ni845xFindDeviceNext ( NiHandle FindDeviceHandle, char * NextDevice ); kNI845XExport int32 NI845X_FUNC ni845xCloseFindDeviceHandle( NiHandle FindDeviceHandle ); kNI845XExport int32 NI845X_FUNC ni845xOpen( char * ResourceName, NiHandle * DeviceHandle ); kNI845XExport int32 NI845X_FUNC ni845xClose ( NiHandle DeviceHandle ); kNI845XExport int32 NI845X_FUNC ni845xDeviceLock ( NiHandle DeviceHandle ); kNI845XExport int32 NI845X_FUNC ni845xDeviceUnlock ( NiHandle DeviceHandle ); kNI845XExport void NI845X_FUNC ni845xStatusToString( int32 StatusCode, uInt32 MaxSize, int8 * StatusString ); kNI845XExport int32 NI845X_FUNC ni845xSetIoVoltageLevel( NiHandle DeviceHandle, uInt8 VoltageLevel ); kNI845XExport int32 NI845X_FUNC ni845xSetTimeout( NiHandle DeviceHandle, uInt32 Timeout ); //============================================================================== // // SPI BASIC API FUNCTION PROTOTYPES // //============================================================================== kNI845XExport int32 NI845X_FUNC ni845xSpiWriteRead( NiHandle DeviceHandle, NiHandle ConfigurationHandle, uInt32 WriteSize, uInt8 * WriteData, uInt32 * ReadSize, uInt8 * ReadData ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationOpen ( NiHandle * ConfigurationHandle ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationClose ( NiHandle ConfigurationHandle ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationSetChipSelect ( NiHandle ConfigurationHandle, uInt32 ChipSelect ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationSetClockRate ( NiHandle ConfigurationHandle, uInt16 ClockRate ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationSetClockPolarity ( NiHandle ConfigurationHandle, int32 ClockPolarity ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationSetClockPhase ( NiHandle ConfigurationHandle, int32 ClockPhase ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationSetNumBitsPerSample ( NiHandle ConfigurationHandle, uInt16 NumBitsPerSample ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationSetPort ( NiHandle ConfigurationHandle, uInt8 PortNumber ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationGetChipSelect ( NiHandle ConfigurationHandle, uInt32 * ChipSelect ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationGetClockRate ( NiHandle ConfigurationHandle, uInt16 * ClockRate ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationGetClockPolarity ( NiHandle ConfigurationHandle, int32 * ClockPolarity ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationGetClockPhase ( NiHandle ConfigurationHandle, int32 * ClockPhase ); int32 NI845X_FUNC ni845xSpiConfigurationGetNumBitsPerSample ( NiHandle ConfigurationHandle, uInt16 * NumBitsPerSample ); kNI845XExport int32 NI845X_FUNC ni845xSpiConfigurationGetPort ( NiHandle ConfigurationHandle, uInt8 * PortNumber ); kNI845XExport int32 NI845X_FUNC ni845xDioWritePort ( NiHandle DeviceHandle, uInt8 PortNumber, uInt8 WriteData ); kNI845XExport int32 NI845X_FUNC ni845xDioReadPort ( NiHandle DeviceHandle, uInt8 PortNumber, uInt8 * ReadData ); kNI845XExport int32 NI845X_FUNC ni845xDioWriteLine ( NiHandle DeviceHandle, uInt8 PortNumber, uInt8 LineNumber, int32 WriteData ); kNI845XExport int32 NI845X_FUNC ni845xDioReadLine ( NiHandle DeviceHandle, uInt8 PortNumber, uInt8 LineNumber, int32 * ReadData ); //This function has been deprecated and ni845xDioSetDriverType and //ni845xSetIoVoltageLevel should be used instead. kNI845XExport int32 NI845X_FUNC ni845xDioSetPortVoltageType ( NiHandle DeviceHandle, uInt8 PortNumber, uInt8 Type ); kNI845XExport int32 NI845X_FUNC ni845xDioSetDriverType( NiHandle DeviceHandle, uInt8 DioPort, uInt8 Type ); kNI845XExport int32 NI845X_FUNC ni845xDioSetPortLineDirectionMap ( NiHandle DeviceHandle, uInt8 PortNumber, uInt8 Map ); #ifdef __cplusplus } #endif #endif // __Ni845x_HEADER__
此签名似乎在.net框架中有效:
[DllImport("Ni845x.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] public static extern Int32 ni845xSpiWriteRead(ulong DeviceHandle, ulong ConfigurationHandle, UInt32 WriteSize, [In] byte[] WriteData, out UInt32 ReadSize, [Out] byte[] ReadData);
因此,是否有任何文档说明.Net Core如何/为什么正确处理'out'声明?
我为National Instruments SPI设备提供了一个包装器-它在.Net Core中可完美运行。我想包装一个UI包装,因此将同一包装器推入.Net Framework。在那里,大多数电话都能正常工作,...
请参见上面的编辑以获取答案。只是不断插电-现在都可以使用。我猜.Net Core是跨平台的,它在PInvoke和Interop方面具有更多/更好的启发式方法?是否由于某些原因未在.NEt Framework上使用相同的内容?是否有任何文档说明.Net Core如何/为何有所不同?