繁体   English   中英

'无法封送'返回值':无效的托管/非托管类型组合。' 用字符串数组编组委托时

[英]'Cannot marshal 'return value': Invalid managed/unmanaged type combination.' while marshalling delegate with string array

我试图封送一个函数指针的委托。 委托的返回类型是字符串数组,而函数指针的返回类型是char **

下面的代码引发无效的托管/非托管类型组合异常。 我该如何解决?

//  unmanaged code

typedef char** (*MyFuncPtr)(void);

class __declspec(dllexport) MyUnmanagedClass{
private:
    MyFuncPtr mFunPtr
public:

    MyUnmanagedClass(MyFuncPtr funPtr)
    {
        mFunPtr = funPtr;
    }

    char* Func1()
    {
        //  callback
        mFunPtr();

        return "something";
    }
};

//  managed wrapper (CLI)

public delegate cli::array<String^>^ MyDelegate();

public class MyCliClass{
private:
    MyDelegate mDel;
public:

    MyCliClass(MyDelegate del)
    {
        mDel = del;
    }

    String^ Func2()
    {
        MyFuncPtr funPtr = static_cast<MyFuncPtr>(Marshal::GetFunctionPointerForDelegate(mDel).ToPointer());

        MyUnmanagedClass* muc = new MyUnmanagedClass(funPtr);
        char* retValPtr = muc->Func1();

        return context->marshal_as<String^>(retValPtr);
    }   
};

//  managed client (C#)
class Program
{
    static void Main( string[] args )
    {
        MyCliClass mcc = new MyCliClass(Func3);
        mcc.Func2();
    }

    static string[] Func3()
    {
        return new[] { "Some 1", "Some 2" };
    }
}

这就是我终于解决的方法...

//  unmanaged code
class __declspec(dllexport) NativeInterface
{
public:
    vector<string> NativeInterfaceFunc() = 0;
};

class __declspec(dllexport) UnmanagedClass{
private:
    NativeInterface* mNativeInterface
public:

    UnmanagedClass(NativeInterface* nativeInterface)
    {
        mNativeInterface = nativeInterface;
    }

    string UnmanagedClassFunc()
    {
        vector<string> values = mNativeInterface->NativeInterfaceFunc();

        ostringstream oss;

        copy(values.begin(), values.end(), ostream_iterator<string>(oss, ","));

        return oss.str();
    }
};

//  managed wrapper (CLI)
class NativeClass : NativeInterface
{
public:
    NativeInterface(ManagedInterface^ managedInterface)
    {
        mManagedInterface = managedInterface        
    };

    vector<string> NativeInterfaceFunc()
    {
        IEnumerable<String^> managedReturn = mManagedInterface->ManagedInterfaceFunc();

        vector<string> nativeReturn;

        marshal_context^ context = new marshal_context();

        for each(String^ manRet in managedReturn)
        {
            nativeReturn.push_back(context->marshal_as<const char*>(manRet))
        }

        delete context;

        return nativeReturn;
    };
private:
    gcroot<ManagedInterface^> mManagedInterface;
};

public ref class CliClass{
public:

    CliClass(ManagedInterface^ managedInterface)
    {
        mNativeInterface = new NativeClass(managedInterface);

        mUnmanagedClass = new UnmanagedClass(mNativeInterface);
    }

    ~CliClass()
    {
        delete mUnmanagedClass;
        delete mNativeInterface;
    }

    String^ CliFunc()
    {
        string nativeReturn = mUnmanagedClass->UnmanagedClassFunc();

        return gcnew String(nativeReturn.c_str());
    }   
private:
    UnmanagedClass mUnmanagedClass;
    NativeInterface mNativeInterface;
};

//  managed interface (C#)
interface ManagedInterface
{
    IEnumerable<string> ManagedInterfaceFunc();
}

//  managed interface implementation(C#)
public class ManagedClass : ManagedInterface
{
    public IEnumerable<string> ManagedInterfaceFunc()
    {
        return new List<string> { "Some 1", "Some 2" };
    }
}

//  managed client (C#)
class Program
{
    static void Main( string[] args )
    {
        MyCliClass mcc = new MyCliClass(new ManagedClass());

        Console.WriteLine(mcc.CliFunc());

        mcc.Dispose();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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