草庐IT

c# - 困惑: instance creation of c# class in c++

coder 2023-06-02 原文

假设 someClass 是一个用 C# 定义的类,带有一些方法 int doSomething(void),并且为简单起见,提供一个不带参数的构造函数。然后,在 C# 中,必须在 gc 堆上创建实例:

someClass c;                   // legit, but only a null pointer in C#
// c->doSomething()            // would not even compile. 
c = new someClass();           // now it points to an instance of someclass.
int i = c->doSomething();      

现在,如果someClass被编译成一些.Net库,你也可以在C++/CLI中使用它:

someClass^ cpp_gcpointer = gcnew someClass();
int i = cpp_gcpointer->doSomething();

就这么简单!漂亮!这当然是假设对 .Net 库的引用已添加到项目中,并且已做出相应的 using 声明。

据我了解,这是与前面的 C# 示例完全相同的 C++/CLI 示例(浓缩为一行,这不是我感兴趣的重点)。正确的? (对不起,我是这个话题的新手)

然而,在 C++ 中,也

someClass cpp_cauto;              // in C++ declaration implies instantiation
int i = cpp_cauto.doSomething(); 

是有效的语法。出于好奇,我今天尝试了这个。一位同事看着我的肩膀,愿意打赌它甚至不会编译。他会输掉赌注。 (这仍然是 C# 程序集中的类)。实际上,它也产生与前面示例中的代码相同的结果 i

也很漂亮,但是 - 嗯 - 它到底是什么,这里创造了什么?我的第一个疯狂猜测是,在我背后,.Net 在 gc 堆上动态创建一个实例,而 cpp_auto 是该对象的某种包装器,其语法行为类似于类 someClass<>。但后来我找到了这个页面

http://msdn.microsoft.com/en-us/library/ms379617%28v=vs.80%29.aspx#vs05cplus_topic2

此页面似乎告诉我,(至少,如果 someClass 是 C++ 类)cpp_auto 实际上是在堆栈上创建的,据我所知,这与您得到的行为相同在经典 C++ 中。还有一些你不能在 C# 中做的事情(你不能,可以吗?)。我想知道的是:来自 C# 程序集的实例是否也在堆栈上创建?您可以在 C++ 中使用无法在 C# 中创建的堆栈上的类实例生成 .Net 二进制文件吗?这甚至可能会给您带来性能提升:-) 吗?

亲切的问候,

托马斯

最佳答案

link you referenced详细解释:

C++/CLI allows you to employ stack semantics with reference types. What this means is that you can introduce a reference type using the syntax reserved for allocating objects on the stack. The compiler will take care of providing you the semantics that you would expect from C++, and under the covers meet the requirements of the CLR by actually allocating the object on the managed heap.

基本上,它仍在对托管堆上的引用类型进行处理,但是当它超出您的范围时,会自动在 IDisposable 实现上调用 Dispose() .

然而,对象实例仍然通过 gcnew 有效分配(放置在托管堆上)并由垃圾收集器收集。这也有详细解释:

When d goes out of scope, its Dispose method will be called to allow its resources to be released. Again, since the object is actually allocated from the managed heap, the garbage collector will take care of freeing it in its own time.

基本上,这一切都由编译器处理,以使代码看起来和工作起来像标准 C++ 堆栈分配的类,但它实际上只是一个编译器技巧。生成的 IL 代码仍在进行托管堆分配。

关于c# - 困惑: instance creation of c# class in c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8247862/

有关c# - 困惑: instance creation of c# class in c++的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  4. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  5. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  6. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  7. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  8. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  9. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  10. ruby - Ruby 中字符串运算符 + 和 << 的区别 - 2

    我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc

随机推荐