Frage

I am passing a C# object (PSObject) to managed C++ in the following way. But it crashes in the commented statement. Am I missing something?

Am I passing PSObject correctly to managed C++? or am I accessing it wrongly?

I am using clr:oldsyntax.

Actually C# will pass a PSObject to managed C++, in managed C++ I want to examine the properties present in PSObject. (An object returned by running PowerShell commands)

In C#, using delegate concept I am calling managed C++ method to pass PSObject. The delegate is declared as below:

delegate bool CFuncDelegate(PSObject Arg);

funcObj (a IntPtr) is a pointer to addData function in C++ (I didn't write that code here, since it is not relevant) and I am calling addData in csharp as:

CFuncDelegate func = (CFuncDelegate)Marshal.GetDelegateForFunctionPointer(funcObj, typeof(CFuncDelegate));
bool isCompleted = func(psoObject); //psoObject is a PSObject

and in managed C++,

static bool __clrcall addData(System::Management::Automation::PSObject* curPsObj)
{
    log(Marshal::StringToHGlobalUni(curPsObj->AdaptedMemberSetName));  
    //prints psadapted

    System::Object* value = curPsObj->Properties->get_Item("DisplayName");   
    //crashes
}

It would be better if someone just post two lines of code to pass object from C# and accessing it in managed C++. Thanks in advance.

War es hilfreich?

Lösung

I think it's really time that you abandoned oldsyntax and moved to C++/CLI. Anyway, even doing that is not going to solve your problem. You define a delegate like this:

delegate bool CFuncDelegate(PSObject Arg);

And then you assign a delegate variable like this:

CFuncDelegate func = (CFuncDelegate)Marshal.GetDelegateForFunctionPointer(
    funcObj, typeof(CFuncDelegate));

The documentation for Marshal.GetDelegateForFunctionPointer says:

Converts an unmanaged function pointer to a delegate.

So, your code can only work if funcObj is an unmanaged function. And your addData method is certainly not that. You need to stop using GetDelegateForFunctionPointer here. It is simply not compatible with calling the managed function addData.

I've no idea where funcObj comes from. You said:

funcObj (a IntPtr) is a pointer to addData function in cpp (i didnt write that code here, since it is not relevant)

In fact it is not only relevant to the problem, it is the root cause of the problem. What I would expect to see here would be for you to add the C++ assembly to your C# project as a reference, at which point addData could be referenced directly.

Of course, none of this even mentions the fact that your calling conventions are mis-matched. The managed code uses clrcall and your unmanaged function pointer is taken to be stdcall.

Update

There's some more information in the comments. Pass addData as a delegate. You'll need to declare the delegate type in the C# code which I believe you reference from your C++ assembly.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top