如何通过 Visual Studio COM 包装器(或其他方式)在 C# 中使用 C++ 属性联合

Posted

技术标签:

【中文标题】如何通过 Visual Studio COM 包装器(或其他方式)在 C# 中使用 C++ 属性联合【英文标题】:How to use C++ property union in C# through Visual Studio COM wrapper(or some other means) 【发布时间】:2012-09-28 19:51:10 【问题描述】:

我正在尝试使用制造商提供的 com/dlls(用 c++ 编写)与设备通信,但是我遇到了一个问题,即我无法在结构中设置字段的值。

在 C++ 中,这个结构体根据提供的文档是这样实现的:

typedef struct tagFCITEST

  FCITESTTYPE TestType;
  [switch_type( FCITESTTYPE ), switch_is( TestType )]
  union
  
    [case(FCI_TYPE_PROPORTIONAL)] FCI_TEST_PROPORTIONAL Test;
    [case(FCI_TYPE_SWITCH)] FCI_TEST_SWITCH SwitchTest;
    [default];
  ;
 FCITEST;

但是,当我在 Visual Studio 中“转到定义”时,我发现以下内容:

public struct tagFCITEST

    public __MIDL___MIDL_itf_mftFCINTF_0209_0005 __MIDL_0022;
    public tagFCITESTTTYPE TestType;

public struct __MIDL___MIDL_itf_mftFCINTF_0209_0005


显然 C# 不支持这些类型的联合,并且看起来 Visual Studio 在创建包装器时搞砸了,所以我尝试了以下方法来解决这个问题:

    public struct tagFCITEST
    
        public MFTFCINTFLib.tagFCITESTTTYPE TestType;
        public __MIDL___MIDL_itf_mftFCINTF_0209_0005 __MIDL_0022;
    

    [StructLayout(LayoutKind.Explicit)]
    public struct __MIDL___MIDL_itf_mftFCINTF_0209_0005
    
        [FieldOffset(0)]
        public MFTFCINTFLib.tagFCI_TEST_PROPORTIONAL Test;
        [FieldOffset(0)]
        public MFTFCINTFLib.tagFCI_TEST_SWITCH SwitchTest;
    

如果我在方法调用中使用我的自定义结构,编译器会不高兴,并告诉我存在无效的争论。即使我要创建自定义方法签名:

    [DllImport("mftFCINTF.dll")]
    public static extern void DownloadTag(int ISessionID,
        string szwDeviceTag,
        string szwDeviceSeriaINum,
        ref MFTFCINTFLib.tagFCICOMMDEF pCommDef,
        ref MFTFCINTFLib.tagFCIDEVIN pInputDef,
        ref MFTFCINTFLib.tagFCIDEVOUT pOutputDef,
        ref MFTFCINTFLib.tagFCIDEVRELATION pRelationDef,
        ref tagFCITEST pTestDef,        // This is the changed line
        string szwSetupInstructions,
        string szwCleanupInstructions,
        out string pszwLocationInCalibrator,
        out MFTFCINTFLib.tagFCISTATUS pStatus);

没有使用签名。有没有办法修改 Visual Studio 的包装器实现?或者也许有更好的方法来解决这个问题?

谢谢!

编辑:

这是生成的 .IDL 文件

// Generated .IDL file (by the OLE/COM Object Viewer)
// 
// typelib filename: mftFCINTF.dll

[
  uuid(C81FC550-84AC-437B-AD0E-DA283ACE4687),
  version(1.0),
  helpstring("mftFCINTF 1.0 Type Library"),
  custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 83951780),
  custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1058814716)

]
library MFTFCINTFLib

    // TLib :     // TLib : OLE Automation : 00020430-0000-0000-C000-000000000046
    importlib("stdole2.tlb");

    // Forward declare all types defined in this typelib
    interface ICalibratorInfo;
    interface ICalibratorDownload;
    interface ICalibratorUpload;
    interface IConfigurator;

    [
      uuid(34E98744-678E-4D9A-B57F-6A96521BB609),
      helpstring("MFT 1.0 by Meriam Process Technologies")
    ]
    coclass mftFCI 
        [restricted] interface ICalibratorInfo;
        [restricted] interface ICalibratorDownload;
        [restricted] interface ICalibratorUpload;
        [restricted] interface IConfigurator;
    ;

    [
      odl,
      uuid(FF5EFD41-7B15-11D1-B326-00001CBE02AA),
      version(1.0),
      helpstring("ICalibratorInfo Interface")
    ]
    interface ICalibratorInfo : IUnknown 
        HRESULT _stdcall DriverProperties([out] tagFCISTATUS* pStatus);
        HRESULT _stdcall Open(
                        [in] int nPortNumber, 
                        [out] long* plSessionId, 
                        [out] long* plCapabilities, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall Close(
                        [in] long lSessionId, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall Properties(
                        [in] long lSessionId, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall GetId(
                        [in] long lSessionId, 
                        [out] LPWSTR* pszwCalManufacturer, 
                        [out] LPWSTR* pszwCalModel, 
                        [out] LPWSTR* pszwCalSerialNum, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall GetCalDates(
                        [in] long lSessionId, 
                        [out] _SYSTEMTIME* pLastCalDate, 
                        [out] _SYSTEMTIME* pNextCalDueDate, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall SetDateAndTime(
                        [in] long lSessionId, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall SetTempStandard(
                        [in] long lSessionId, 
                        [in] int nTemperatureStd, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall GetTestResultsCount(
                        [in] long lSessionId, 
                        [out] int* pnCount, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall ClearMemory(
                        [in] long lSessionId, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall ValidateTag(
                        [in] tagFCICOMMDEF* pCommDef, 
                        [in] tagFCIDEVIN* pInputDef, 
                        [in] tagFCIDEVOUT* pOutputDef, 
                        [in] tagFCIDEVRELATION* pRelationDef, 
                        [in] tagFCITEST* pTestDef, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall GetSensorModuleId(
                        [in] long lSessionId, 
                        long nSensorIndex, 
                        [out] LPWSTR* pszwCalManufacturer, 
                        [out] LPWSTR* pszwCalModel, 
                        [out] LPWSTR* pszwCalSerialNum, 
                        [out] LPWSTR* pszwCalDate, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall ClearCalFatEntry(
                        [in] long nIndex, 
                        [out, retval] VARIANT_BOOL* pResult);
        HRESULT _stdcall SetAppDriverMode([in] long nMode);
    ;

    typedef enum 
        FCI_OK = 0,
        FCI_FAILED = 1,
        FCI_COMM_ERROR = 2,
        FCI_REVISION_ERROR = 3,
        FCI_CANCELED = 4,
        FCI_NOT_SUPPORTED = 5,
        FCI_ALREADY_OPEN = 6,
        FCI_WRONG_SESSION = 7,
        FCI_WRONG_CALIBRATOR = 8,
        FCI_ERR_IN_RANGE = 9,
        FCI_ERR_IN_UNITS = 10,
        FCI_ERR_IN_TYPE = 11,
        FCI_ERR_IN_MANUAL = 12,
        FCI_ERR_OUT_RANGE = 13,
        FCI_ERR_OUT_UNITS = 14,
        FCI_ERR_OUT_TYPE = 15,
        FCI_ERR_OUT_MANUAL = 16,
        FCI_ERR_INOUT = 17,
        FCI_ERR_RELATION = 18,
        FCI_ERR_PROBE = 19,
        FCI_ERR_CJC = 20,
        FCI_ERR_ENUM = 21,
        FCI_ERR_RESOURCE = 22,
        FCI_ERR_TESTPOINT = 23,
        FCI_ERR_TESTTYPE = 24,
        FCI_ERR_POWER = 25,
        FCI_ERR_TAG = 26,
        FCI_MEM_FULL = 27,
        FCI_MEM_EMPTY = 28,
        FCI_MEM_HAS_DATA = 29,
        FCI_END_OF_UPLOAD = 30,
        FCI_ERR_DOWNLOAD = 31,
        FCI_ERR_TAGLENGTH = 32,
        FCI_ERR_SNLENGTH = 33,
        FCI_ERR_MAXPOINTS = 34,
        FCI_END = 35
     tagFCISTATUS;

    typedef struct tag_SYSTEMTIME 

unsigned short wYear;

unsigned short wMonth;

unsigned short wDayOfWeek;

unsigned short wDay;

unsigned short wHour;

unsigned short wMinute;

unsigned short wSecond;

unsigned short wMilliseconds;
     _SYSTEMTIME;

    typedef struct tagtagFCICOMMDEF 

tagFCICOMMTYPE CommType;

__MIDL___MIDL_itf_mftFCINTF_0209_0001 __MIDL_0016;
     tagFCICOMMDEF;

    typedef enum 
        FCI_COMMTYPE_NONE = 1,
        FCI_COMMTYPE_HART = 2
     tagFCICOMMTYPE;

    typedef union tag__MIDL___MIDL_itf_mftFCINTF_0209_0001 

tagFCI_COMMDEF_HART HartData;
     __MIDL___MIDL_itf_mftFCINTF_0209_0001;

    typedef struct tagtagFCI_COMMDEF_HART 

unsigned char cBlockId;

unsigned char cURev;

unsigned char cPollAddr;

unsigned char acUid[5];

unsigned char acTag[6];

unsigned char acDescriptor[12];

unsigned char acDate[3];

unsigned char acMessage[24];
     tagFCI_COMMDEF_HART;

    typedef struct tagtagFCIDEVIN 

tagFCIBLOCKTYPE DevType;

__MIDL___MIDL_itf_mftFCINTF_0209_0002 __MIDL_0017;
     tagFCIDEVIN;

    typedef enum 
        FCI_BLKTYPE_GENERIC = 1,
        FCI_BLKTYPE_TEMP_RTD = 2,
        FCI_BLKTYPE_TEMP_TC = 3,
        FCI_BLKTYPE_FREQUENCY = 4,
        FCI_BLKTYPE_PRESSURE = 5,
        FCI_BLKTYPE_TEMP_MEASRTD = 6,
        FCI_BLKTYPE_TEMP_MEASTC = 7,
        FCI_BLKTYPE_HART = 8,
        FCI_BLKTYPE_SWITCH = 9,
        FCI_BLKTYPE_DIFFTEMP = 10
     tagFCIBLOCKTYPE;

    typedef union tag__MIDL___MIDL_itf_mftFCINTF_0209_0002 

tagFCI_BLKDEF_PRESSURE PressureData;

tagFCI_BLKDEF_RTD TempRtdData;

tagFCI_BLKDEF_TC TempTcData;

tagFCI_BLKDEF_RTD TempMeasRtdData;

tagFCI_BLKDEF_TC TempMeasTcData;

tagFCI_BLKDEF_FREQUENCY FrequencyData;

tagFCI_BLKDEF_HART HartData;

tagFCI_BLKDEF_DIFFTEMP DiffTempData;

tagFCI_BLKDEF_GENERIC GenericData;
     __MIDL___MIDL_itf_mftFCINTF_0209_0002;

    typedef struct tagtagFCI_BLKDEF_PRESSURE 

single rURV;

single rLRV;

single rSettling;

unsigned short wUnits;

unsigned short wPressureType;
     tagFCI_BLKDEF_PRESSURE;

    typedef struct tagtagFCI_BLKDEF_RTD 

single rURV;

single rLRV;

single rSettling;

unsigned short wUnits;

unsigned short wProbeType;

unsigned short wNumWires;

unsigned short wRESERVED;
     tagFCI_BLKDEF_RTD;

    typedef struct tagtagFCI_BLKDEF_TC 

single rURV;

single rLRV;

single rSettling;

single rManualCJC;

unsigned short wUnits;

unsigned short wProbeType;

unsigned short wCJC;

unsigned short wProbeConnect;
     tagFCI_BLKDEF_TC;

    typedef struct tagtagFCI_BLKDEF_FREQUENCY 

single rURV;

single rLRV;

single rSettling;

single rAmplitude;

unsigned short wUnits;

unsigned short wWaveForm;
     tagFCI_BLKDEF_FREQUENCY;

    typedef struct tagtagFCI_BLKDEF_HART 

single rUSL;

single rLSL;

single rSettling;

unsigned short wUnits;
     tagFCI_BLKDEF_HART;

    typedef struct tagtagFCI_BLKDEF_DIFFTEMP 

single rURV;

single rLRV;

single rSettling;

unsigned short wUnits;

unsigned short wDeviceVariable1;

unsigned short wDeviceVariable2;
     tagFCI_BLKDEF_DIFFTEMP;

    typedef struct tagtagFCI_BLKDEF_GENERIC 

single rURV;

single rLRV;

single rSettling;

unsigned short wUnits;
     tagFCI_BLKDEF_GENERIC;

    typedef struct tagtagFCIDEVOUT 

tagFCIBLOCKTYPE DevType;

__MIDL___MIDL_itf_mftFCINTF_0209_0003 __MIDL_0018;
     tagFCIDEVOUT;

    typedef union tag__MIDL___MIDL_itf_mftFCINTF_0209_0003 

tagFCI_BLKDEF_PRESSURE PressureData;

tagFCI_BLKDEF_RTD TempMeasRtdData;

tagFCI_BLKDEF_TC TempMeasTcData;

tagFCI_BLKDEF_FREQUENCY FrequencyData;

tagFCI_BLKDEF_HART HartData;

tagFCI_BLKDEF_SWITCH Switch;

tagFCI_BLKDEF_GENERIC GenericData;
     __MIDL___MIDL_itf_mftFCINTF_0209_0003;

    typedef struct tagtagFCI_BLKDEF_SWITCH 

unsigned short wContactType;

unsigned short wForm;

unsigned short wTripDirection;

single rWetContactVoltage;
     tagFCI_BLKDEF_SWITCH;

    typedef struct tagtagFCIDEVRELATION 

tagFCIRELATIONTYPE RelType;

__MIDL___MIDL_itf_mftFCINTF_0209_0004 __MIDL_0020;
     tagFCIDEVRELATION;

    typedef enum 
        FCI_RELTYPE_LINEAR = 0,
        FCI_RELTYPE_SQRT = 1,
        FCI_SQRT_3RD_PWR = 2,
        FCI_SQRT_5TH_PWR = 3,
        FCI_RELTYPE_TABLE = 4,
        FCI_RELTYPE_SWITCH = 230
     tagFCIRELATIONTYPE;

    typedef union tag__MIDL___MIDL_itf_mftFCINTF_0209_0004 

tagFCI_RELDEF_SQRT SqrtData;

tagFCI_RELDEF_TABLE TableData;
     __MIDL___MIDL_itf_mftFCINTF_0209_0004;

    typedef struct tagtagFCI_RELDEF_SQRT 

single rBreakPoint;
     tagFCI_RELDEF_SQRT;

    typedef struct tagtagFCI_RELDEF_TABLE 

unsigned short wNumPoints;

unsigned short wInterpolate;

single rInput[30];

single rOutput[30];
     tagFCI_RELDEF_TABLE;

    typedef struct tagtagFCITEST 

tagFCITESTTTYPE TestType;

__MIDL___MIDL_itf_mftFCINTF_0209_0005 __MIDL_0022;
     tagFCITEST;

    typedef enum 
        FCI_TYPE_PROPORTIONAL = 1,
        FCI_TYPE_SWITCH = 2
     tagFCITESTTTYPE;

    typedef union tag__MIDL___MIDL_itf_mftFCINTF_0209_0005 

tagFCI_TEST_PROPORTIONAL Test;

tagFCI_TEST_SWITCH SwitchTest;
     __MIDL___MIDL_itf_mftFCINTF_0209_0005;

    typedef struct tagtagFCI_TEST_PROPORTIONAL 

unsigned short wRESERVED;

unsigned short wPowerSource;

unsigned short wCalSourceInput;

unsigned short wCalReadInput;

unsigned short wCalMeasureOutput;

unsigned short wNumTestPoints;

single arTestPoint[21];

single rTestPointTolerance;

single rAdjustmentLimit;

single rMaxErrorLimit;
     tagFCI_TEST_PROPORTIONAL;

    typedef struct tagtagFCI_TEST_SWITCH 

single rTripSetPoint;

single rTripTolerance;

single rResetDeadband;

single rDeadbandTolerance;

single rRampTime;

long bTestReset;
     tagFCI_TEST_SWITCH;

    [
      odl,
      uuid(FF5EFD42-7B15-11D1-B326-00001CBE02AA),
      version(1.0),
      helpstring("ICalibratorDownload Interface")
    ]
    interface ICalibratorDownload : IUnknown 
        HRESULT _stdcall StartDownloading(
                        [in] long lSessionId, 
                        [in] LPWSTR szSessionName, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall DownloadTag(
                        [in] long lSessionId, 
                        [in] LPWSTR szwDeviceTag, 
                        [in] LPWSTR szwDeviceSerialNum, 
                        [in] tagFCICOMMDEF* pCommDef, 
                        [in] tagFCIDEVIN* pInputDef, 
                        [in] tagFCIDEVOUT* pOutputDef, 
                        [in] tagFCIDEVRELATION* pRelationDef, 
                        [in] tagFCITEST* pTestDef, 
                        [in] LPWSTR szwSetupInstructions, 
                        [in] LPWSTR szwCleanupInstructions, 
                        [out] LPWSTR* pszwLocationInCalibrator, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall FinishDownloading(
                        [in] long lSessionId, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall AbortDownload(
                        [in] long lSessionId, 
                        [out] tagFCISTATUS* pStatus);
    ;

    [
      odl,
      uuid(FF5EFD43-7B15-11D1-B326-00001CBE02AA),
      version(1.0),
      helpstring("ICalibratorUpload Interface")
    ]
    interface ICalibratorUpload : IUnknown 
        HRESULT _stdcall StartUploading(
                        [in] long lSessionId, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall UploadNextTag(
                        [in] long lSessionId, 
                        [out] LPWSTR* pszwLocationInCalibrator, 
                        [out] LPWSTR* pszwDeviceTag, 
                        [out] LPWSTR* pszwDeviceSerialNum, 
                        [out] LPWSTR* pszwTechnician, 
                        [out] LPWSTR* pszwServiceNote, 
                        [out] int* pnTemperatureStd, 
                        [out] tagFCICOMMDEF* pCommDef, 
                        [out] tagFCIRESULT* pAsFound, 
                        [out] tagFCIRESULT* pAsLeft, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall FinishUploading(
                        [in] long lSessionId, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall AbortUpload(
                        [in] long lSessionId, 
                        [out] tagFCISTATUS* pStatus);
        HRESULT _stdcall PreviewNextTag(
                        [in] long lSessionId, 
                        [out] LPWSTR* pszwLocationInCalibrator, 
                        [out] LPWSTR* pszwDeviceTag, 
                        [out] LPWSTR* pszwDeviceSerialNum, 
                        [out] long* plRecordType, 
                        [out] _SYSTEMTIME* pDate, 
                        [out] tagFCISTATUS* pStatus);
    ;

    typedef struct tagtagFCIRESULT 

tagFCITESTTTYPE ResultType;

__MIDL___MIDL_itf_mftFCINTF_0209_0006 __MIDL_0024;
     tagFCIRESULT;

    typedef union tag__MIDL___MIDL_itf_mftFCINTF_0209_0006 

tagFCI_RESULT_PROPORTIONAL Results;

tagFCI_RESULT_SWITCH SwitchResults;
     __MIDL___MIDL_itf_mftFCINTF_0209_0006;

    typedef struct tagtagFCI_RESULT_PROPORTIONAL 

double dInputLowerRangeValue;

double dInputUpperRangeValue;

int nInputRangeUnits;

double dOutputLowerRangeValue;

double dOutputUpperRangeValue;

int nOutputRangeUnits;

int nRelationship;

int nNumberOfTestPoints;

double adInput[21];

double adOutput[21];

LPWSTR szwAuxEquipManufacturer;

LPWSTR szwAuxEquipModel;

LPWSTR szwAuxEquipSerialNum;

double dAmbientTemperature;

int nAmbientTemperatureUnits;

_SYSTEMTIME TestDate;
     tagFCI_RESULT_PROPORTIONAL;

    typedef struct tagtagFCI_RESULT_SWITCH 

unsigned short wUnits;

single rTripPoint;

single rResetPoint;

unsigned short bResetTested;

_SYSTEMTIME TestDate;

LPWSTR szwAuxEquipManufacturer;

LPWSTR szwAuxEquipModel;

LPWSTR szwAuxEquipSerialNum;
     tagFCI_RESULT_SWITCH;

    [
      odl,
      uuid(084ABD42-30CE-49AD-B1FA-9C869AAD2A27),
      version(1.0),
      helpstring("IConfigurator Interface")
    ]
    interface IConfigurator : IUnknown 
        [helpstring("method UploadConfiguration")]
        HRESULT _stdcall UploadConfiguration(
                        long* pDataAvailabe, 
                        BSTR bstrFilePath, 
                        [in, out] BSTR* pbstrTag, 
                        [in, out] long* plDof, 
                        [in, out] long* plAsFoundAsLeft, 
                        [in, out] long* pnLocation, 
                        [in, out] long* pnMultivar, 
                        [in, out] BSTR* pbstrDeviceSerialNum, 
                        [out, retval] VARIANT_BOOL* pResult);
        [helpstring("method DownloadConfiguration")]
        HRESULT _stdcall DownloadConfiguration(
                        [in] BSTR bstrFilePath, 
                        [in, out] long* pnLocation, 
                        [out, retval] VARIANT_BOOL* pResult);
        [helpstring("method ClearConfiguratorMemory")]
        HRESULT _stdcall ClearConfiguratorMemory();
        [helpstring("method GetConfigCount")]
        HRESULT _stdcall GetConfigCount([out, retval] long* lCount);
        [helpstring("method PreviewConfiguration")]
        HRESULT _stdcall PreviewConfiguration(
                        long* pDataAvailabe, 
                        [in, out] BSTR* pbstrTag, 
                        [in, out] long* plDof, 
                        [in, out] long* plAsFoundAsLeft, 
                        [in, out] long* plOrigin, 
                        [in, out] long* pnLocation, 
                        [in, out] BSTR* pbstrDeviceSerialNum, 
                        [out] _SYSTEMTIME* pDate, 
                        [out, retval] VARIANT_BOOL* pResult);
        [helpstring("method SetPortNumber")]
        HRESULT _stdcall SetPortNumber(long nPort);
        [helpstring("method ClearConfigFatEntry")]
        HRESULT _stdcall ClearConfigFatEntry(
                        long nIndex, 
                        [out, retval] VARIANT_BOOL* pResult);
    ;
;

【问题讨论】:

如果您使用 OLE-COM 对象查看器(它将在与 Visual Studio OleView.Exe 一起安装的 windows SDK 文件夹中),转到类型库,找到 iterface 并右键单击并转到到View...(如果这是您第一次这样做,请以管理员身份运行程序,因为它需要在第一次执行View 时注册一个DLL。)将生成的.IDL 文件粘贴为您的问题的编辑.请注意,该程序有 32 位和 64 位版本。 Visual Studio 在 x64 系统上只将 64 位版本放在开始菜单中,但您可以进入该文件夹并运行 32 版本。 【参考方案1】:

毫无疑问,这些声明是通过导入 COM 服务器的类型库得到的。通过添加对 COM dll 的引用或手动运行 Tlbimp.exe。

是的,这是个问题,类型库只支持可以用 IDL 表达的子集。这些受歧视的工会当然不是其中的一部分。它们仅对于使结构正确地编组跨越公寓边界很重要,只有代理/存根 DLL 需要正确查看它们,这是自动生成的代码。

解决问题的两种基本方法,都不是特别愉快:

您可以编辑从类型库生成的互操作库并修复结构声明。首先使用 ildasm.exe 反编译 DLL,编辑 IL 并将其与 ilasm.exe 重新组合在一起。您可以使用反编译的示例 C# 程序来查看 IL 应该是什么样子。这可行,但重要的是 COM 组件是稳定的,因此您不必一遍又一遍地执行此操作。 MSDN 中有一个How-To article 描述了该过程。

用 C++/CLI 语言为组件编写一个包装器。您可以 #include 由来自 IDL 的 midl.exe 生成的 .h 文件。显然,只有当您有权访问 IDL 或拥有 .h 文件时,这才有效,如果您没有它,则需要联系供应商或作者。这样做的一个好处是您还可以规避其他类型的问题。缺点是您需要了解 C++ 语言和 COM 客户端编程的基础知识。

【讨论】:

我试图在我拥有的两个 dll 上运行 ildasm,但我得到了相同的错误“错误:‘xxx.dll’没有有效的 CLR 标头并且不能被反汇编“在这一点上,我唯一的选择是向制造商索取必要的文件吗?谢谢! 不要在 COM dll 上运行它,在由它生成的互操作库上运行它。 成功了,谢谢!我会看看我是否能找到如何修改这个 il 文件以使其工作... 看起来我所要做的就是在它在中间语言文件中创建的结构下为联合添加不同的字段以使其工作。非常感谢! 庆祝得太早了,结果即使我摆脱了关于类型转换的编译器错误,我仍然收到关于字段编组的运行时错误......

以上是关于如何通过 Visual Studio COM 包装器(或其他方式)在 C# 中使用 C++ 属性联合的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 如何加载库?

如何在 Visual Studio 2008 安装项目中使用 regasm 注册 .NET CCW

在 Visual Studio 2010 Express 中从 dll 自动生成 C# 包装类?

如何在没有 Visual Studio 的情况下进行调试?

Visual Studio:C++\CLI 包装器程序集路径依赖问题

使用 Visual Studio 或 Resharper 用区域包装所有方法和属性