简体   繁体   中英

Passing in C# enum to a wrapper method parameter of C++ CLI

I have a following C++/CLI class.

public ref class QADotNetAPI {
public:
    QADotNetAPI() {

    }

    ~QADotNetAPI() {
        QTTerminate();
    }

    int SomeMethod(const char *ch) {
        return Something(ch);
    }

    .
    .
    .

    int IsValid(QTQualifier *pstate) {
        return QTIsValid(QTFeatureIdEnum::_QT_FEATURE_ALL, pstate);
    }
};

.
.
.

// The method in unmanaged code ( Not within QADotNetAPI scope )
QT_API QTErrorCode QTIsValid(const QTFeatureId eFeatureId, QTQualifier *eState );

.
.
.

// The enum, QTQualifier. ( Not within QADotNetAPI scope )
typedef enum  QTQualifierEnum
{
   QT_QUALIFIER_OUT_OF_RANGE, 
   QT_QUALIFIER_CORRECTABLE, 
   QT_QUALIFIER_VALID,
   QT_QUALIFIER_LAST
} QTQualifier;

I injected this C++/CLI class above into C# application. I can successfully invoke the SomeMethod . I can make it because I know what kind of value to pass into that function.

But I don't know what to pass in for the QTIsValid method.

public enum QaEnum {
    OUTOFRANGE,
    CORRECTABLE,
    VALID,
    LAST
}

private void button1_Click(object sender, EventArgs e)
{
    QADotNetAPI qa = new QADotNetAPI();
    int rst= qa.Init();           
    rst = qa.IsValid(ref QaEnum.VALID); // Doesn't work
    // rst = qa.IsValid(out QaEnum.VALID); // Doesn't work too

    // rst = qa.IsValid(?????) // WHAT TO PASS IN ??
}

Some say that "share the enum throughout C++/CLI and C# project". I tried that using a bunch of enum declarations and shared them via dll on both C++/CLI and C# projects but to no avail.

Also, I tried with struct . Again, it didn't work. What can I do for a C++/CLI consumable enum?

The current signature of IsValid accepts only a pointer:

int IsValid(QTQualifier *pstate) 
{
  return QTIsValid(QTFeatureIdEnum::_QT_FEATURE_ALL, pstate);
}

So my expectation is that for C# that is shown as IntPtr. (Honestly I would expect that for the C# Compiler the method wouldn't be usable at all.) My suggestion ist to change IsValid as follows:

int IsValid(int state) 
{
  // TODO: check argument is valid
  QTQualifier nativeState = static_cast<QTQualifier>(state); 
  return QTIsValid(QTFeatureIdEnum::_QT_FEATURE_ALL, &nativeState);
}

That should work.

A more type safe version could be this

public enum class QaEnum
{
  OUTOFRANGE,
  CORRECTABLE,
  VALID,
  LAST
}

int IsValid(int state) 
{
  // TODO: check if argument is valid (.NET enums are also only integers)
  QTQualifier nativeState = static_cast<QTQualifier>(state); 
  return QTIsValid(QTFeatureIdEnum::_QT_FEATURE_ALL, &nativeState);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM