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

标签 c# c++ com pinvoke

我正在尝试使用制造商提供的 com/dll(用 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# 不支持这些类型的 union ,而且 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);
    };
};

最佳答案

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

是的,这是一个问题,类型库仅支持可以用 IDL 表达的内容的子集。而这些受歧视的 union 当然不属于其中。它们仅对于使结构正确地跨越单元边界进行编码很重要,只有代理/ stub DLL 需要正确地查看它们,这就是自动生成的代码。

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

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

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

关于c# - 如何通过 Visual Studio COM 包装器(或其他方式)在 C# 中使用 C++ 属性 union ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12646488/

相关文章:

c# - vba 可扩展性,com 插件指导?

c# - 为什么 .Equals 在此 LINQ 示例中不起作用?

c# - 如何: Create a Key In the Registry (Visual C#)?

c# - 项目无法识别包含在不同程序集中的构造函数

c++ - Gale Shapley 首选项生成

c++ - 二进制计算器减法

c# - 将 Windows 8 应用程序连接到 MySQL

c++ - 将类型分配给 typename 关键字

javascript - 在 C++ 的 JScript 中调用 instanceof 运算符 (IDispatch/IDispatchEx)

c# - 如何从 C++ 向 COM 公开带有 IHTMLDocument* 类型参数的方法?