SUMTEC -- There's a thing in my bloglet.

But it's not only one. It's many. It's the same as other things but it exactly likes nothing else...

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  263 随笔 :: 19 文章 :: 3009 评论 :: 74万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

最近需要用到一些CLR内部的东西,例如StrongName等等,于是需要用C++来写。但是全部用C++来写感觉太累人了,所以我决定用C++扩展的方式写一个Wrapper,然后其他东西在C#里面写。可是C++扩展的文档实在是太累人了——资料残缺不全不说,有些东西还是英文的……

比如说怎么从Managed字符串转换成Unmanaged的字符串,反过来应该怎么样做,找这些资料简直就是累死人了。后来发现这个还是比较好找的:

#using
using namespace System;

void ShowU()
{
  String *Filename;
  TCHAR __pin * pinnedFilename;

  TCHAR *somethingElse;
  String ManagedSomethingElse;

  Filename = new String(“File“);
  pinnedFilename = PtrToStringChars(Filename);

  somethingElse = “Something else“;
  MangedSomethingElse = new String(somethingElse);
}

还有,怎么才能够把一个参数写成C#里面的ref byte类型,也费了不少周折。资料里面是这么说的:

C# 函数:
public void SomeFunc(ref int x) { x = 2; }
MC++ 等效函数:
public: void SomeFunc(Int32* x) { *x = 2; }
它要求在调用 SomeFunc 前对参数进行明确赋值。
此外,使用 C++ 引用表述它没有任何问题。在元数据中,除 modopt 外,C++ 引用与 C++ 指针是相同的:
[Microsoft.VisualC]Microsoft.VisualC.IsCXXReferenceModifier.

可是我花了好长时间才搞明白最后那句话的意思。原来每一个托管数据类型都会对应一个非托管的数据类型,如果用的是值,那么是可以完全当作同一个类型,但是如果用的是指针,那就有很大差别了。比如说System::Boolean和bool,如果:

bool a;
System::Boolean b;
a = b;

这是成立的,但是:

bool *a;
System::Boolean *b;
a = b;

却是不成立的。解决的办法是:

bool __pin *a;
System::Boolean *b;
a = b;

但是对于参数来说,又有一些其它的问题了:

void Any(bool &a, bool __gc &b, System::Boolean *d)
{
}

这里面的a、b、c的il表达是不一样的:

.method public static void  GetKeyFly(
bool* modopt([Microsoft.VisualC]Microsoft.VisualC.IsCXXReferenceModifier) a,
bool& modopt([Microsoft.VisualC]Microsoft.VisualC.IsCXXReferenceModifier) b,
bool& c)

我想,资料里面最后的那句话说的应该是b和c之间的区别吧,我一开始还以为是a和b的区别呢!真是搞死人了!a在C#里面绝对不是ref bool类型的,千万别搞错了。

用了几天C++托管扩展,感觉确实是一个托管和非托管之间的桥梁,工作的非常好,但是同时也是我觉得VC++是前所未有的混乱,__pin/__gc/__nogc/__box/__unbox/__try/__trycast,还有托管和非托管类型的对应关系……

现在我还有一个疑问:怎么将非托管的东西变成private的?现在全部是public的,弄了好多乱七八糟的东西出来,比如

.class private explicit ansi sealed $ArrayType$0xea34fe7f
       extends [mscorlib]System.ValueType

弄出来没有关系,别弄成public就行了,不然到了C#下面智能提示乱七八糟、乌烟瘴气的!谁知道怎么做?可以告诉我吗?


文章来源:http://dotnet.blogger.cn/sumtec/archive/2004/03/18/430.aspx
posted on   Sumtec  阅读(966)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
点击右上角即可分享
微信分享提示