如何从C#引用类型转换为CLI \ C ++ ^%类型… [英] How to convert from C# ref type to CLI\C++ ^% type…

查看:80
本文介绍了如何从C#引用类型转换为CLI \ C ++ ^%类型…的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用托管C ++(CLI \ C ++)编写应用程序.我正在其中使用用C#编写的库(.dll文件).
在某种程度上,我遇到了一个问题.
我正在尝试实现库中编写的接口的功能.

库中的函数声明如下:

I am writing an application in Managed C++ (CLI\C++). In which I am using a library (.dll file) which was written in C#.
In a part I am encountering a problem.
I am trying to implement functions of an interface written in the library.

The declaration of a function in the library is as given below:

COMWORKSPACELib.IWorkspaceEvents.WorkspaceMessage(int, string, COMWORKSPACELib.EnumNotificationCode, COMWORKSPACELib.EnumNotificationType, string, ref COMWORKSPACELib.EnumNotificationReply);



当我在CLI \ C ++中编写相同的代码时,声明就像:



When I write the same code in CLI\C++ the declaration is like:

WorkspaceMessage(int workspaceToken, String ^description, EnumNotificationCode ^code, EnumNotificationType ^type, String ^source, EnumNotificationReply ^%action);



在这里,编译器给我一个错误,即类必须提供接口方法的实现".因为在两个函数声明中传递的参数在语法上都不同.

有没有其他方法可以匹配库声明?

如果我删除"^"& %"以匹配库声明,然后会在代码中提供更多错误.


下面,我正在编写一个示例代码,描述实际代码的编写方式...

接口ISampleInter C#:-



Here, the compiler is giving me error that the "class must provide an implementation for the interface method". Because the parameters passed in both function declarations are syntactically different.

Is there any alternative way to match the library declaration?

If I remove the "^’ & ‘%’ to match the library declaration then it gives further errors in the code.


Below I am writing a sample code depicting the way actual code is written...

Interface ISampleInter C#: -

namespace LibraryName
{
    public interface ISampleInter
    {
        Void Method1(int nfir, String str, ref EnumType type);
        Void Method2(int nsec, EnumCode code, String str, ref EnumType type);
    }
}



注意:-添加了包含此接口的库,作为对主项目的引用...

MyCode C ++/CLI:-
MyCode.h



Note: - A Library containing this interface is added as a reference to the main project...

MyCode C++/CLI: -
MyCode.h

using namespace LibraryName;

namespace WorkSpace
{
    private ref class WorkMyClass : ISampleInter
    {
        public:
            virtual Method1(int nfir, String str, EnumType %type);
            virtual Method2(int nsec, EnumCode code, String str, EnumType %type);
    };
}



MyCode.cpp



MyCode.cpp

#included "MyCode.h"

using namespace LibraryName;

namespace WorkSpace
{
    void Method1(int nfir, String str, EnumType %type)
    {
        //Some Code;
    }

    void Method2(int nsec, EnumCode code, String str, EnumType %type)
    {
        //some Code;
    }
}

推荐答案

尽管SA的回答有点苛刻,但他是对的.引用程序集后,intellisense将为您显示所需的类型.

由于枚举是值类型,因此不需要将其与^一起传递.试试这个:

Even though SA''s answer is a little bit harsh, he''s right. After referencing the assembly, intellisense will show you the expected types.

Since an enum is a value type, you don''t need to pass it with ^. Try this:

virtual void WorkspaceMessage(int workspaceToken, System::String^ description, EnumNotificationCode code, EnumNotificationType type, System::String^ source, EnumNotificationReply %action)
{
}



...

在.h中,输入以下内容:



...

In the .h, write the following:

using namespace LibraryName;
namespace WorkSpace
{
    private ref class WorkMyClass : ISampleInter
    {
        public:
            virtual void Method1(int nfir, System::String^ str, EnumType %type);
            virtual void Method2(int nsec, EnumCode code, System::String^ str, EnumType %type);
    };
}


在.cpp文件中,输入以下内容:


In the .cpp, write the following:

#include "MyCode.h"
using namespace LibraryName;
using namespace WorkSpace;
void WorkMyClass::Method1(int nfir, System::String^ str, EnumType %type)
{
    //Some Code;
}

void WorkMyClass::Method2(int nsec, EnumCode code, System::String^ str, EnumType %type)
{
    //some Code;
}


在提交示例代码后回答后续问题:

您已经犯了很多错误;方法实现部分中最主要的一个是语法错误.两种产品都无法编译.这里应该是:

接口ISampleInter C#:

Answering a follow-up Question after the sample code is submitted:

You have done good number of bugs; most principal one is wrong syntax in method implementation part. Both products would not compile. Here is what should be:

Interface ISampleInter C#:

namespace LibraryName {
    using System; //added

    public enum EnumType { None, Some, } //fake, just to make code compile
    public enum EnumCode { Good, Bad, } //fake, just to make code compile

    //"void" was incorrectly capitalized, fixed:
    public interface ISampleInter {
        void Method1(int nfir, String str, ref EnumType type);
        void Method2(int nsec, EnumCode code, String str, ref EnumType type);
    } //interface ISampleInter

} //namespace LibraryName



附带说明:ref的两个参数没有意义,使它们返回值;为什么使用void?但是,我们的目标是检查技术,因此让我们继续:

MyCode.h:



A side note: two parameters by ref make no sense, make them return values; why using void? However, our goal is to check-up techniques, so let''s proceed:

MyCode.h:

using namespace LibraryName;
using namespace System; //added

namespace WorkSpace
{
    private ref class WorkMyClass : ISampleInter
    {
        public:
            //two problems:
            //1) added "void":
            //2) added "^" for String -- this is reference type

            virtual void Method1(int nfir, String ^str, EnumType %type);
            virtual void Method2(int nsec, EnumCode code, String ^str, EnumType %type);
    };
}



MyCode.cpp:



MyCode.cpp:

using namespace LibraryName;
using namespace System; //added

namespace WorkSpace {

    //two problems:
    //1) added "^" for String -- this is reference type
    //2) added "WorkMyClass::" common C++ syntax

    void WorkMyClass::Method1(
        int nfir,
        String ^str,
        EnumType %type)
    {
        //Some Code;
    }
    void WorkMyClass::Method2(
        int nsec,
        EnumCode code,
        String ^str,
        EnumType %type)
    {
        //some Code;
    }

}



现在是正确的.如果我不知道的某些类型是引用类型,则需要通过引用使用"^%"而不是%"作为参数.

我会说,结案了.

—SA



Now it''s correct. If some of the types I don''t know is a reference type, you need to use "^%" instead of "%" for a parameter by reference.

I would say, case closed.

—SA


难怪您的代码不会编译:如果您要实现接口,则需要编写每个方法和属性的实现.编写所有参数的匹配声明可能是您自己的问题.

好像您完全混合了托管,非托管的引用,指针和地址运算符的所有可能组合.您需要了解"*",&"(非托管)和"^",%"托管之间的区别.但是现在,您可以简单地依靠intellisense:在编写实现之前,尝试声明对对象实例的接口引用并对其方法进行调用.键入开括号后,intellisense会立即显示所有预期的结果.

简而言之,您将看到:
C#,通过值传递的值类型:(int a) — C ++/CLI:相同:(int a)
C#,由ref传递的值类型:(ref int a) — C ++/CLI:相同:(int %a)
C#,按值传递的引用类型:(string a) — C ++/CLI:(string ^a)
C#,由ref传递的引用类型:(ref string a) — C ++/CLI:(string ^%a).

最后一种情况是愚蠢的,但是您可以正式使用它.

C#中还有一个out参数,它与ref相似,但始终需要在方法主体中进行赋值.在C#中,在调用中还使用了匹配的refout参数修饰符,这使C#语法更加简单.但它们未在C ++/CLI中使用.

另外,%"是地址"运算符的类似物,用于从引用类型的值中获取引用:
No wonder you code does not compile: if you''re implementing the interface, you need to write implementation of every method and property. Probably, your own problem in writing matching declaration of all parameters.

It looks like you completely mixing up all possible combinations of references, pointers and address operators, managed and unmanaged, all together. You need to learn the difference between ''*'', ''&'' (unmanaged) and ''^'', ''%'' managed. But right now you can simply let rely on intellisense: before you write implementation, try to declare the interface reference to the object instance and write a call to its method. As soon as you type an open bracket intellisense will show you all what''s expected.

In brief, you will see:
C#, value type passed by value: (int a) — C++/CLI: the same: (int a)
C#, value type passed by ref: (ref int a) — C++/CLI: the same: (int %a)
C#, reference type passed by value: (string a) — C++/CLI: (string ^a)
C#, reference type passed by ref: (ref string a) — C++/CLI: (string ^%a).

The last case is kind of stupid, but formally you can use it.

There is also out parameter in C#, which is similar to ref but always requires assignment in the method body. In C#, matching ref and out parameter modifiers are also used in the call, which makes C# syntax more fool-proof; but they are not used in C++/CLI.

Also, ''%'' is the analog of "address" operator used to get a reference from value of a reference type:
ref class Demo {
    void Test() {
        Demo demoVal;
        Demo^ demoRef = %demoVal;
        Demo^ demoHeapRef = gcnew Demo();
    }
};


demoRef的示例中演示的带有类的值语义对于C ++/CLI是唯一的. C#中没有这样的东西,因此所有引用类型都是在堆上分配的,并且只能通过引用来寻址,因此等效于demoRef的变量声明是不可能的(但对于值类型的结构则是可能的).
现在,您需要了解所有四种情况在语义上的含义,然后才尝试理解该表示法.
尝试不同的组合以希望它可以编译甚至奇迹般地运行是……什么是政治上正确的表达方式?..适得其反…

祝你好运,

—SA
在提交代码示例后回答后续问题:请参阅另一个答案.


The value semantic with classes demonstrated on the example of demoRef is unique to C++/CLI. There is no such thing in C#, so all reference types are allocated on heap and only addressed by reference, so the variable declaration equivalent to demoRef is not possible (but possible with structures, which are value types).

Now you need to learn what all four cases mean semantically and only then try to understand the notation.
Trying different combination in hope it will compile and even run miraculously is… what''s the politically correct expression?.. counterproductive…

Good luck,

—SA
Answering follow-up Question after code samples are submitted: see another Answer.


这篇关于如何从C#引用类型转换为CLI \ C ++ ^%类型…的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆