我将c#对象(PSObject)以以下方式传递给托管c++。但是它在注释语句中崩溃了。我错过什么了吗?
我传递PSObject正确的管理c++ ?还是我访问错了?
我使用的是clr:oldsyntax
。
实际上c#将PSObject传递给托管c++,在托管c++中,我想检查PSObject中存在的属性。(运行PowerShell命令返回的对象)
在c#中,使用委托概念,我调用托管c++方法来传递PSObject。委托声明如下:
delegate bool CFuncDelegate(PSObject Arg);
funcObj (a IntPtr)是指向c++中addData
函数的指针(我没有在这里编写代码,因为它不相关),我在csharp中调用addData为:
CFuncDelegate func = (CFuncDelegate)Marshal.GetDelegateForFunctionPointer(funcObj, typeof(CFuncDelegate));
bool isCompleted = func(psoObject); //psoObject is a PSObject
和在托管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
}
如果有人只是发布两行代码从c#传递对象并在托管c++中访问它会更好。
我认为是时候放弃oldsyntax
并转向c++/CLI了。无论如何,即使这样做也不能解决你的问题。您可以这样定义委托:
delegate bool CFuncDelegate(PSObject Arg);
然后像这样分配一个委托变量:
CFuncDelegate func = (CFuncDelegate)Marshal.GetDelegateForFunctionPointer(
funcObj, typeof(CFuncDelegate));
Marshal.GetDelegateForFunctionPointer
的文档说:
将非托管函数指针转换为委托。
所以,你的代码只能工作,如果funcObj
是一个非托管函数。你的addData
方法肯定不是这样的。您需要在这里停止使用GetDelegateForFunctionPointer
。它根本不兼容调用托管函数addData
。
我不知道funcObj
是从哪里来的。你说:
事实上,它不仅与问题有关,而且是问题的根本原因。我希望在这里看到的是你将c++程序集作为参考添加到你的c#项目中,这样funcObj (a IntPtr)是指向cpp中addData函数的指针(我没有在这里写代码,因为它不相关)
addData
就可以直接引用了。
当然,这些都没有提到调用约定不匹配的事实。托管代码使用clrcall
,而非托管函数指针则采用stdcall
。
评论中有更多的信息。将addData
作为委托传递。您需要在c#代码中声明委托类型,我相信您从c++程序集中引用了这些代码。