Interop(交互) Between C# and C++ 研究一

在进行这一个研究前,首先得有一个思想:语言只是一个工具,不同的语言在不同的平台与环境下发挥不同的作用,而你的权利是在选择.有一次我要开发一个关于视频点播系统(事实上这一个系统没什么用处)的时候,发现C#不是很合适进行对Directshow的开发.一个方面是directx在C#环境下对Directshow的支持比较少,另一个方面是在存在Directshow.net(一个开源项目,是把directshow封装在.Net环境下调用)情况下,如果你想用它来写SourceFilter的话还是显得有点困难,因为你不是很容易调用系统较底层一点的API,都得用C#封装一下很麻烦.然后后面写这一个文章的动机可能是我自己个人的问题,我总是认为用C++做出来的界面难度大且不好看,但对C#来说就会很不一样,想开发成像vs2005界面那样左右都有可隐藏的窗口都要比用C++开发一个简单界面容易些.所以最后面这一个系统的开发方案是用C++实现directshow的source
filter与网络通信,然后通过COM技术封装成一个Player.dll让C#调用.而在此过程当中会遇到很多C++与C#的通过COM实现相互调用的问题,我便在此总结了一下我的研究结果,有的也许也没有最终最好的答案,有的研究也许在这里只到一半便放弃了,总之这里是我在寻找思路与解决方案的过程.

有了这一个方案后先开始写一个小小的test:

项目名:InteropWithCSharpAndCPP

    file1.h:

        #pragma once

        #ifdef __WinTest_C_DLL

        #else

        #define __WinTest_C_DLL extern "C"  _declspec(dllimport)

        #endif

        __WinTest_C_DLL int  add(int a,int b);

    file1.cpp:

        #include "file1.h"

        int  add(int a,int b)

        {

            return a+b;

        }

然后再写了一个C++ test 项目:cpptest1

    cpptest1.cpp:

        #include "stdafx.h"

        #include "file1.h"

        using namespace std;

        int _tmain(int argc, _TCHAR* argv[])

        {

            cout<<add(4,2)<<endl;

            getchar();

            return 0;

        }

引用InteropWithCSarpAndCPP.lib与文件file1.h总后输出6测试成功.

然后又再写了一个C#的测试项目:charptest1

    Program.cs:

        using System;

        using System.Collections.Generic;

        using System.Text;

        using System.Runtime.InteropServices;

        namespace charptest1

        {

          class Program

          {

            [DllImport("InteropWithCSharpAndCPP.dll")]

            public static extern int add(int a, int b);

            static void Main(string[] args)

            {

              Console.WriteLine(add(2, 4));

              Console.Read();

            }

          }

        }

同时把InteropWithCSharpAndCPP.dll放到charptest1 bin 目录下,也测试成功.

第一个测试成功,心想这事应该还比较好办.但接着一个问题,就是类的问题,最终Player.dll肯定不可能都用这一种方法的方式给C#调用吧?便开始了第二个简单测试,也就是上面的一个升级版本.突然一想在C#当中调用C++里面的类,还真不太好办,因为DllImport还真不能直接把一个类extern出来,不过后面想到这一种最简单的方法:

Project:WinTest3

Files:

Math.h

#pragma once

extern "C"  _declspec(dllimport) class  Math

{

public:

static Math* instance();

int sub(int a,int b);

static     void deleteMath(void *);

void output(int a,int b);

private:

Math(void);

virtual ~Math(void);

};

Math.cpp

#include "Math.h"

#include <Windows.h>

#include <iostream>

#include <strstream>

#include <sstream>

using namespace std;

Math::Math(void)

{

}

Math* Math::instance()

{

return new Math();

}

void Math::deleteMath(void  * m)

{

Math * mIn=(Math*) m;

delete mIn;

}

int Math::sub(int a,int b)

{

return a-b;

}

void Math::output(int a,int b)//当时随兴突然想在GUI下测试一下

{

HWND hwnd=GetForegroundWindow();

HDC hdc=GetDC(hwnd);

wostringstream  myString;

myString<<"x="<<a<<","<<"y="<<b<<endl;myString.str();

TextOut(hdc,0,0,myString.str().c_str(),wcslen(myString.str().c_str()));

ReleaseDC(hwnd,hdc);

}

Math::~Math(void)

{

}

WinTest_C.def

LIBRARY    "WinTest3"

EXPORTS

add   @1

?[email protected]@@[email protected] @2

?[email protected]@@[email protected]  @3

?[email protected]@@[email protected] @4

?[email protected]@@[email protected] @5

千万别把上面的文件名,类名与方法名以某种联系,其实都是我当时突然想出来做一个测试用的.而文件WinTest_C.def中变形后的方法名是在文件WinTest3.map中找到的,你可以在项目中生成此文件的选项.

然后在C#项目中做一个测试:

Project:WinInterop

Files:

NMath.cs

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

namespace WinInterop

{

class NMath

{

[DllImport("WinTest3.dll", EntryPoint = "[email protected]@@[email protected]", CallingConvention = CallingConvention.ThisCall)]

public static extern int sub(IntPtr the, int a, int b);

[DllImport("WinTest3.dll", EntryPoint = "[email protected]@@[email protected]", CallingConvention = CallingConvention.StdCall)]

public static extern IntPtr CreateMath();

[DllImport("WinTest3.dll", EntryPoint = "[email protected]@@[email protected]", CallingConvention = CallingConvention.StdCall)]

public static extern void DeleteMath(IntPtr instance);

[DllImport("WinTest3.dll", EntryPoint = "[email protected]@@[email protected]", CallingConvention = CallingConvention.ThisCall)]

public static extern void output(IntPtr instance, int a, int b);

}

}

Form1部分:

private void button1_Click(object sender, EventArgs e)

{

IntPtr instance =NMath.CreateMath();

NMath.output(instance, 10, 10);

NMath.DeleteMath(instance);

}

这一个测试成功,界面上能看到输出的结果.

看到上面这一段代码后,相信很多的朋友都会觉得很别扭,觉得真正实现当中怎么可能用这一种方法.首先说为什么我会用Math*
Math::instance()这一种方法来生成类吧.因为在C#项目中,我不知道如何extern出Math的构造方法去生成类.对应的void
Math::deleteMath(void * m) 也是一样的原因啦.然后说到WinTest_C.def的方法名,里面很多变异后的方法名是在.map文件当中找到的,并且你每添加一个方法都得重新生成并找出来,添加到.def文件当中,如果你想修改方法名的话更加烦麻.然后还有NMath里面那么多的static,entrypoint的.这不是一个开发人员应该用的方法,代码写得多,没有结构,并且都还是做一些低级的开发工作,如查找无聊的方法名,当时就对这一种方法脑火了.

上一个方法失败后开始想到IDispatch,IUnKnown等COM技术.但又不想自己全部去实现所有的这一些接口,然后想到用ATL项目开发.这样便开始走入正轨.关于COM的细节与ATL的一些知识我这里不能多说,水平也没达到,但我可以说一下我是如何使用ATL一步步实现我预期的方案的.

版权声明:本文为博主http://www.zuiniusn.com 原创文章,未经博主允许不得转载。

时间: 2024-09-17 00:34:28

Interop(交互) Between C# and C++ 研究一的相关文章

初学交互 总结

交互设计要注意 :1 目标,根据用户(人物角色,用户场景) 2 可用性 3 反馈响应时间 4 易学性提升交互的方法:1 角色扮演交互过程:一个扮演“交互界面”,一个扮演用户,用户与交互界面对话,用户描述使用目标,“交互界面”用UI上的标签或是菜单回应用户.2 地图化体验过程:将每一步体验都记录下来,包括任务和情绪变化3 简化流程步骤:复杂简单化4 少给用户选择5 留意微时刻:用户在交互过程中犹豫,前进,停止的时刻 交互设计是与用户进行一场对话 UED架构报障视觉设计-visual design交

什么是交互设计

交互设计,又称互动设计,英文Interaction Design, 缩写为IxD,是定义.设计人造系统的行为的设计领域. 人造物:即人工制成物品,例如,软件.移动设备.人造环境.服务.可佩带装置以及系统的组织结构. 交互设计在于定义人造物的行为方式(the interaction,即人工制品在特定场景下的反应方式)相关的界面. 交互设计师首先进行用户研究相关领域,以及潜在用户,设计人造物的行为,并从有用性,可用性和情感因素等方面来评估设计质量. 产生原因 交互设计在任何的人工物的设计和制作过程里

开发辅助 | 前端开发工程师对 UI设计、交互设计的认知

1.UI 用户界面 UI:User Interfase 用户界面 UID:User Interfase Designer 用户界面设计师,多指移动 app 的界面设计: 2.一个合格的 UI 设计师,至少应该具备什么? (1)审美: 一个好的设计师,应具备基本的艺术审美,识别不同的艺术表现形式,区分作品的好坏,感受下: 图1:  图2:   (2)想象力.脑洞 比如:克里斯托弗·诺兰导演的电影<盗梦空间>. 宫崎骏的<千与千寻> (3)基本的工具使用: 常用且基本的工具:PS 拓展

CCF虚拟现实与可视化技术专委会丨面向增强现实的可视计算技术研究进展概述

https://mp.weixin.qq.com/s/I-rNwgXHEtwgdpkWzKtVXw 摘要 新一代增强现实技术需要依赖可视计算理论与方法解决大尺度复杂环境下的场景建模.内容生成.感知交互三个关键科学问题.本文从以上三个方面,介绍了面向增强现实的可视计算技术的主要研究进展.其中,场景建模主要涉及复杂场景定位.重建与建模,包括同时定位与地图构建.场景几何与材质精确重建与数字化.实时高质量动态环境重建等:内容生成主要涉及视觉一致性驱动的高逼真度虚实融合,包括场景渲染参数估计.虚拟物体嵌入

在熟练使用2B铅笔前,请不要打开Axure

在互联网产品领域,Axure已成为产品经理.产品设计师以及交互设计师的必备工具,从某种程度讲,Axure帮助我们建立低保真模型,便于与用户的需求验证,也帮助我们构思交互细节,使前端和开发人员更容易理解我们的产品:但从另一方面讲,Axure绑架了我们的思维,让很多产品经理和设计师养成了“无Axure不设计”的恶习,忽略了用户故事.功能规格和信息架构,甚至走入“为了用Axure而用的误区”,导致了资源的大量浪费和产品的硬伤.因此,提醒为Axure着迷的产品经理:在熟练使用2B铅笔前,请不要打开Axu

基于云存储的3D虚拟信息平台

增强现实是把计算机产生的虚拟物体或其他信息合成到用户看到的真实世界中的一种技术.实现虚拟信息与真实景象的正确匹配或有机结合是每个增强现实实用系统都必须完成的一项重要任务,且它的具体实现需依赖于计算机硬件和软件系统的相互配合及协调.并能支持用户与其进行交互,它已经成为虚拟现实研究中的一个重要领域,也是人机界面技术发展的一个重要方向. 在当前科技飞速发展的今天,随着三维激光扫描仪的诞生以及大规模普及,我们项目在后续开发中将进一步提升三维交互的真实感,用户可以通过三维扫描仪或者利用3D建模工具制作的人

性能1——系统性能

1.1.系统性能 系统性能是对整个系统的研究,包括了所有的硬件组件和整个软件栈 系统性能是需要多类人员参与的事务,包括系统管理员.技术支持人员.应用开发者.数据库管理员和网络管理员. 1.2.事情 性能领域包括以下的事情 1.设置性能目标和建立性能模型 2.基于软件或硬件原型进行性能特征归纳 3.对开发代码进行性能分析(软件整合之前) 4.执行软件非回归性测试(软件发布前或发布后) 5.针对软件发布版本的基准测试 6.目标环境中的概念验证 7.生产环境部署的配置优化 8.监控生产环境中运行的软件

移动端兼容性浅析

"移动网民的规模将在2013年底达到5.0亿,增速为19.1%.预计到2017年,移动网民将赶超PC网民,成为互联网的第一大用户群体,移动端将成为网民最主要的上网渠道.互联网的加速渗透和全民移动互联有望在下一个5年实现.在过去的几年时间里,移动智能设备快速普及,配置迅速提升,许多过去在PC端才能完成的需求都转移到了移动端,导致PC端流量也逐渐向移动端转移.未来几年许多互联网产品移动端的流量即将超过PC端,整个互联网的使用场景产生巨大变迁." --<2014年中国移动互联网行业年度

产品设计中先熟练使用铅笔 不要依赖Axure

在互联网产品领域,Axure已成为产品经理.产品设计师以及交互设计师的必备工具,从某种程度讲,Axure帮助我们建立低保真模型,便于与用户的需求验证,也帮助我们构思交互细节,使前端和开发人员更容易理解我们的产品;但从另一方面讲,Axure绑架了我们的思维,让很多产品经理和设计师养成了"无Axure不设计"的恶习,忽略了用户故事.功能规格和信息架构,甚至走入"为了用 Axure而用的误区",导致了资源的大量浪费和产品的硬伤.因此,提醒为Axure着迷的产品经理:在熟练