如何在 C++/CLI 中转发声明方法以匹配“C++”的托管扩展的签名引用托管类型的方法

发布于 2024-09-30 04:49:02 字数 2373 浏览 0 评论 0原文

我想从使用 /clr (C++/CLI) 编译的 C++ 代码调用使用 /clr:oldsyntax (C++ 语法的托管扩展)编译的方法。但是,我在 C++/CLI 中向前声明该方法以使其与“C++ 托管扩展”签名匹配时遇到问题。

使用“C++ 的托管扩展”的版本中的声明如下所示:

void MangToUnMangDateTime(System::DateTime & managedDT, tm& unmangDT);

注意:第一个参数 (managementDT) 是此问题感兴趣的参数。 这会导致该方法出现以下 msil(已找到)使用 ildasm.exe):

.method assembly static void  MangToUnMangDateTime(valuetype [mscorlib]System.DateTime& modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) managedDT,
                                                   valuetype tm* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) unmangDT) cil managed

第一次尝试:

我第一次尝试在 C++/CLI 中转发声明此方法,结果如下:

void MangToUnMangDateTime2(System::DateTime % managedDT, tm& unmangDT);

结果是以下 msil:

.method assembly static void  MangToUnMangDateTime(valuetype [mscorlib]System.DateTime& managedDT,
                                                    valuetype tm* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) unmangDT) cil managed

除了“C++ 托管扩展”版本中包含的附加 modopt MSIL 声明符之外,它匹配:

modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) 

第二次尝试

我第二次尝试在 C++/CLI 中转发声明此方法,如下所示:

MangToUnMangDateTime(System::DateTime & managedDT, tm& unmangDT);

作为旁注,我对在 C++/CLI 中编译的这个方法感到惊讶,因为我预计它希望我在托管上使用 % 语法 这导致了以下 msil:

.method assembly static void  MangToUnMangDateTime(valuetype [mscorlib]System.DateTime* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) managedDT,
                                                   valuetype tm* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) unmangDT) cil managed

这个与 modopt MSIL 声明符匹配,但它是一个指针 * 而不是引用 &

问题:

那么,有没有办法让我在 C++/CLI 中转发声明以匹配“C++ 托管扩展”版本中的签名?也许通过参数上的属性?

约束:我不想修改“C++ 托管扩展”版本。显然,如果我将“C++ 托管扩展”版本修改为按值传递(这可能应该放在第一位):

void MangToUnMangDateTime(System::DateTime managedDT, tm& unmangDT);

那么我可以通过在 C++/CLI 中使用相同的声明来获取匹配的签名。

I'd like to call a method being compiled with /clr:oldsyntax (Managed Extensions for C++ syntax) from c++ code being compiled with /clr (C++/CLI). However, I'm having trouble forward declaring the method in C++/CLI such that it matches up to the "Managed Extensions for C++" signature.

The declaration in the version using "Managed Extensions for C++" looks like:

void MangToUnMangDateTime(System::DateTime & managedDT, tm& unmangDT);

Note: The first parameter (managedDT) is the parameter of interest for this question. This results in the following msil for the method (found using ildasm.exe):

.method assembly static void  MangToUnMangDateTime(valuetype [mscorlib]System.DateTime& modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) managedDT,
                                                   valuetype tm* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) unmangDT) cil managed

First Attempt:

My first attempt to forward declare this method in C++/CLI looked like:

void MangToUnMangDateTime2(System::DateTime % managedDT, tm& unmangDT);

which resulted in the following msil:

.method assembly static void  MangToUnMangDateTime(valuetype [mscorlib]System.DateTime& managedDT,
                                                    valuetype tm* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) unmangDT) cil managed

which matches except for the additional modopt MSIL declarator included in the "Managed Extensions for C++" version:

modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) 

Second Attempt

My second attempt to forward declare this method in C++/CLI looked like:

MangToUnMangDateTime(System::DateTime & managedDT, tm& unmangDT);

As a side note, I was surpised this compiled in C++/CLI since I expected it to want me to use the % syntax on a managed type. This resulted in the following msil:

.method assembly static void  MangToUnMangDateTime(valuetype [mscorlib]System.DateTime* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) managedDT,
                                                   valuetype tm* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) unmangDT) cil managed

This one matches the modopt MSIL declarator, but is a pointer * instead of a reference &.

Question:

So, is there a way for me to forward declare this in C++/CLI to match the signature in the "Managed Extensions for C++" version? Perhaps via an attribute on the parameter?

Constraints: I do not want to modify the "Managed Extensions for C++" version. Clearly, if I modify the "Managed Extensions for C++" version to be passed by value (which it probably should have been in the first place):

void MangToUnMangDateTime(System::DateTime managedDT, tm& unmangDT);

then I can get the signatures to match by using the same declaration in C++/CLI.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

网白 2024-10-07 04:49:02

我可能完全错了,但我们不应该首先考虑由“C++ 托管扩展”生成的 IL 被破坏了吗?为什么要向引用参数添加 IsImplicitlyDereferenced 属性?

从这个角度来看,我想这是一个答案,说明您可能无法使用 C++/CLI 生成完全相同的签名(但这实际上是一件好事),并且您的第一次尝试确实是正确的方法去。

I may be completely wrong, but shouldn't we consider the IL produced by "Managed Extensions for C++" broken in the first place ? Why would you add an IsImplicitlyDereferenced attribute to a reference parameter ?

From this point of view, I guess it's an answer to state that you probably won't be able to produce the exact same signature with C++/CLI (but that's actually a good thing), and that your first attempt was indeed the correct way to go.

葮薆情 2024-10-07 04:49:02

您可能想要使用 ^ (System::DateTime^) - 这在 C++/CLI 中声明托管引用。我对 /oldsyntax 一无所知,但它需要引用 CLR 类型,所以我认为这是等效的。

You probably want to use ^ (System::DateTime^)- this declares a managed reference in C++/CLI. I don't know anything about /oldsyntax, but it takes a reference to a CLR type, so I'm thinking that this is the equivalent.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文