。Net Core中的Interop在Framework中失败

问题描述 投票:0回答:1

我为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 .net-core interop
1个回答
0
投票

请参见上面的编辑以获取答案。只是不断插电-现在都可以使用。我猜.Net Core是跨平台的,它在PInvoke和Interop方面具有更多/更好的启发式方法?是否由于某些原因未在.NEt Framework上使用相同的内容?是否有任何文档说明.Net Core如何/为何有所不同?

© www.soinside.com 2019 - 2024. All rights reserved.