起因

项目涉及u3d/wpf端的渲染图形合成,采用了开源项目spout,为了便捷,采用了spout的com版本作为c#端的调用

项目调整后,细节已经捋清楚了。

但是考虑桌面应用采用anypc,根据运行环境自动切换x86/x64,就不想硬编码绑定运行环境了。

故选项后采用 程序选择anypc,运行时动态判断x86/x64,加载对应的com组件

封装代理层,代理层调用对应的x86/x64 com pinvoke

封装分析

项目 LightjamsSpout

我们需要封装的部分是

GLContext和LightjamsSpoutReceiver

都是com接口,硬编码直接实例化即可,动态调用时,不能实例化接口,需要通过反射拿到类型上面的特性 CoClassAttribute

通过获取 CoClassAttribute.CoClass 拿到实际类型去实例化

将x86/x64的库分别放在不同的路径,通过判断 IntPtr.Size == 4/!Environment.Is64BitProcess 判断是否是x86,反之则为x64

通过项目的引用,把com组件转换成 Interop.xx.dll ,路径为项目文件/obj/Debug,项目动态加载实际上是这个 Interop.xx.dll

代码实现

代理端动态加载Assmebly

            loadDirectory = Path.Combine(Directory.GetCurrentDirectory(), IntPtr.Size == 4 ? "x86_Spout" : "x64_Spout");//LightjamsSpoutPS.dll
var loadFile = Path.Combine(loadDirectory, "Interop.LightjamsSpoutLib.dll"); assembly = Assembly.LoadFile(loadFile); var type = assembly.GetType("LightjamsSpoutLib.LightjamsSpoutReceiver");
var coClassAttribute = type.GetCustomAttribute<CoClassAttribute>(); try
{
instance = Activator.CreateInstance(coClassAttribute.CoClass);
}
catch (Exception e)
{
RegisterCom(loadDirectory);
instance = Activator.CreateInstance(coClassAttribute.CoClass);
}

通过表达式树构建实例的方法

比如LightjamsSpoutReceiver.Connect

        delegate string ConnectInvoke(string senderName, out int width, out int height);

        private ConnectInvoke CreateConnect()
{
var senderNameParam = Expression.Parameter(typeof(string), "senderName");
var widthParam = Expression.Parameter(typeof(int).MakeByRefType(), "width");
var heightParm = Expression.Parameter(typeof(int).MakeByRefType(), "height"); var instanceExp = Expression.Constant(instance);
var method = instance.GetType().GetMethod("Connect"); var callExp = Expression.Call(instanceExp, method, new Expression[]{ senderNameParam, widthParam, heightParm }); return Expression.Lambda<ConnectInvoke>(callExp, new ParameterExpression[]{ senderNameParam, widthParam, heightParm }).Compile();
}

值得一提的是type.MakeByRefType是生成type对应的引用类型

毕竟定义是

public virtual string Connect(string senderName, out int width, out int height)

类型转换

有一个函数ReceiveImage,参数调用了com内部类型

public virtual void ReceiveImage(System.Array bytes, LightjamsSpoutLib.EPixelFormat format)

LightjamsSpoutLib.EPixelFormat是com内部的自定义枚举类型

根据内容,做一个枚举类型

    public enum NePixelFormat
{
BGR,
RGB
}

表达式树的参数2改为int,内部转换 Expression.Convertint 转换成对应的 LightjamsSpoutLib.EPixelFormat

调用函数的参数2改为NePixelFormat,内部调用委托时,转换成int即可

        public void ReceiveImage(System.Array bytes, NePixelFormat format)
{
_receiveImage.Invoke(bytes, (int)format);
}

.net下com调用支持x86/x64的更多相关文章

  1. x86 x64下调用约定浅析

    x86平台下调用约定 我们都知道x86平台下常用的有三种调用约定,__cdecl.__stdcall.__fastcall.我们分别对这三种调用约定进行分析. __cdecl __cdecl是C/C+ ...

  2. 使用CefSharp在C#访问网站,支持x86和x64

    早已久仰CefSharp大名,今日才得以实践,我其实想用CefSharp来访问网站页面,然后抓取html源代码进行分析,如果使用自带的WebBrowser控件,可能会出现一些不兼容js的错误. Cef ...

  3. 关于.NET编译的目标平台(AnyCPU,x86,x64) (转)

    关于.NET编译的目标平台(AnyCPU,x86,x64)(转) 今天有项目的代码收到客户的反馈,要求所有的EXE工程的目标平台全部指定成x86,而所有DLL工程的目标平台全部指定成AnyCPU . ...

  4. windows7内核分析之x86&x64第二章系统调用

    windows7内核分析之x86&x64第二章系统调用 2.1内核与系统调用 上节讲到进入内核五种方式 其中一种就是 系统调用 syscall/sysenter或者int 2e(在 64 位环 ...

  5. X86/X64处理器体系结构及寻址模式

    由8086/8088.x86.Pentium发展到core系列短短40多年间,处理器的时钟频率差点儿已接近极限.尽管如此,自从86年Intel推出386至今除了添加一些有关流媒体的指令如mmx/sse ...

  6. 关于VS项目平台的x86,x64,Any CPU以及Debug和Release的区别

    相信对于很多刚接触打包程序的同志来说,关于x86,x64,Any CPU这三个项目平台,以及解决方案配置Debug和Release有什么区别?这个问题一定有许多的困惑,甚至不乏一些已经工作了很久的老程 ...

  7. 『开源重编译』System.Data.SQLite.dll 自适应 x86 x64 AnyCPU 重编译

    背景: > System.Data.SQLite.dll 程序集 不能良好的支持 AngCPU 格式 System.Data.SQLite.dll 在 适应 x86 和 x64 有三个方案: & ...

  8. 数据库管理工具GUI - PremiumSoft Navicat Premium Enterprise 11.2.15 x86/x64 KEY

    转载自: 数据库管理工具GUI - PremiumSoft Navicat Premium Enterprise 11.2.15 x86/x64 KEY Navicat Premium(数据库管理工具 ...

  9. QtCreator动态编译jsoncpp完美支持x86和arm平台

    如果是做嵌入式开发. 在Qt下支持JSon最好的办法,可能不是采用qjson这个库.QJson这个库的实例只提供了x86环境下的编译方法. Installing QJson-------------- ...

随机推荐

  1. FL studio系列教程(十四):如何在FL Studio播放列表中排列样式

    我们在FL Studio中做好了节奏样式后就可以在播放列表窗口中进行乐曲的编排了.刚接触这款软件的同学肯定会对如何编排比较陌生但也比较憧憬的,因为它是从一个窗口到另一个窗口中的操作.其实明白了这里的知 ...

  2. 如何清理MacBook电脑缓存?

    使用Mac电脑的用户都知道,Mac其空间硬盘大多数都是只有128G以及256G的规格,而用惯了win系统基本都是超过512G的硬盘的用户,转手来使用Mac电脑,就不得不接受这一硬伤问题. 用户往往再怎 ...

  3. zabbix地图显示全国延迟

    Zabbix 地图显示全国延迟 1.  效果图 2.  实现方法 将地图.png上传到zabbix为背景,上传红绿点.png为图标.然后新建主机关联模板为ICMP Ping,新建一个拓扑图调用地图为背 ...

  4. Java中的第三大特性-多态性

    一.多态性的概念 多态性是以继承为基础上的,举个例子,人属于动物,狗也属于动物,所以动物就是父类,而人和狗都是动物的子类,都属于动物. 二.多态的使用 (1)多态一般用于方法参数或者方法返回值,特别当 ...

  5. 蓝桥杯——复数幂 (2018JavaAB组第3题)

    18年Java蓝桥杯A组第3题和B组是一样的. 第三题往往比较难. 复数幂 (18JavaAB3) (A.B两卷第三题一样) 设i为虚数单位.对于任意正整数n,(2+3i)^n 的实部和虚部都是整数. ...

  6. 学会了这一招,距离Git大神不远了!

    大家好,今天我们来介绍git当中一项非常重要的功能--交互式工具 有的时候如果我们要处理的文件很多,使用git add .等操作会非常有隐患,因为很有可能我们一不小心就疏忽了一些内容.如果我们使用一个 ...

  7. [整理]qbxt集训10场考试 大 杂 烩 (后篇)

    前篇 Contest 6 A 两个数,第 \(i\) 轮从较大数(如果相等就是第一个)里减去 \(i\) ,问操作不能进行时两数分别为多少. 首先把大数减到和小数差不多,然后我们会发现接下来两数会轮流 ...

  8. 色相偏移 HueShift ASE

    色相偏移可以改变颜色色调,unity ASE没有参考UE4写个,原理很简单,将颜色向量绕(1,1,1)旋转,就可以得到不同色调的颜色. https://zhuanlan.zhihu.com/p/677 ...

  9. 【NOIP2017提高A组模拟9.12】Arrays and Palindrome

    [NOIP2017提高A组模拟9.12]Arrays and Palindrome[SPJ] 题目 Description Input Output Sample Input 1 6 Sample O ...

  10. CentOS下Mysql的操作

    重启Mysql的各种方法 1.通过rpm包安装的MySQL service mysqld restart /etc/inint.d/mysqld start 2.从源码包安装的MySQL // lin ...