如何在没有不安全修饰符的情况下将c#类对象传递给托管c++

本文关键字:对象 c++ 情况下 不安全 | 更新日期: 2023-09-27 18:03:12

我将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++中访问它会更好。

如何在没有不安全修饰符的情况下将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是从哪里来的。你说:

funcObj (a IntPtr)是指向cpp中addData函数的指针(我没有在这里写代码,因为它不相关)

事实上,它不仅与问题有关,而且是问题的根本原因。我希望在这里看到的是你将c++程序集作为参考添加到你的c#项目中,这样addData就可以直接引用了。

当然,这些都没有提到调用约定不匹配的事实。托管代码使用clrcall,而非托管函数指针则采用stdcall

评论中有更多的信息。将addData作为委托传递。您需要在c#代码中声明委托类型,我相信您从c++程序集中引用了这些代码。