您的位置:首页 > 编程语言 > C#

com和c#的一些笔记

2015-09-18 15:16 549 查看
        写作原因:记录一些关于com的使用的注意事件,还有c#怎么调用c/c++的代码。

        背景:上次在网上有看见一篇文章,这个文章里面提到一个"野生程序员"的概念,我发现我自己比较像野生程序员。我大学是数学专业的工作是码代码,所以我学习新技术或者是编程语言基本都是:1.有时间就找一本网上推荐的书籍,快速看一遍,接下来就是搭建环境,直接编程。2.项目紧的话就跳过快速看书的步骤直接快速熟悉了解一下,搭建环境,编程。所以导致的问题就是我接触的东西比较广,但是自己精力有限,就变成了对什么都了解不透彻,这在我以后找工作的劣势很明显。就像现在需要com组件和c#一样就是工作需要,临时学习,马上动手,所以遇见一些细节问题就卡壳。废话说多了,直接记录东西吧!

       1.只有一个com的dll文件,如何在c/c++代码里面调用这个com组件。

方法:先把这个组件注册到自己的系统上面,再利用vs提供的工具OLE-COM Object Viewer找到你的组件,一般是在Type Libraries里面找,找到之后点击查看,你就可以看见这个com组件导出了哪些接口,接口有哪些函数,甚至是一些结构体的定义,选择上面的保存就会保存成一个对应的idl文件,接下来就好了。那么直接把idl拖到项目里面去,编译就会生成对应的.h和.c文件,如果有错误就修改一下。有了这两个文件你就可以在你的项目里面使用这个com组件了。

      2.c#中怎么调用c/c++的com组件已经c的dll文件。

方法:调用com组件可以直接在c#的引用里面找到对应的组件添加进来,直接调用。还有就是把组件需要的coclass和interface定义出来,再调用

例如:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

namespace ConsoleApplication1
{
[ComImport]
[ClassInterface(ClassInterfaceType.None)]
[Guid("B79D8069-DA72-4DD4-B466-4F9EEB96257A")]
public class njTestClass
{
}[ComImport]
[ClassInterface(ClassInterfaceType.None)]
[Guid("E38068B7-9464-4FB5-B26C-332E892D4917")]
public class njTestTow
{
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0EEF9EAC-746B-413F-AAA8-3BCC23854253"), CoClass(typeof(njTestClass))]
public interface InjTestClass
{
void showData(out int data);
}[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("CB58BD3E-CBDF-49D4-A689-0B6A2A1298A5"), CoClass(typeof(njTestTow))]
public interface InjTestTow
{
void TestTow(out int uData, [In] int uTmp);
void propgetTest([Out, In] ref int data);
}
}

就是按照com组件声明出来,直接使用就行了。有些是需要修改类型什么的,这个就需要网上找一下怎么修改了。

如果com是自己写的就需要注意了

http://www.cnblogs.com/deliver/archive/2012/12/08/2808959.html
http://www.cppblog.com/fwxjj/archive/2010/09/12/126429.aspx

这两个上面有说明,我这里也列举一下(免得再去跳网页了),编译的问题,因为c#默认是any CPU,正常c/c++都是x86,所以修改c#的工程配置。com的接口问题dispinterface接口、Dual接口以及Custom接口。要不会报错找不到组件或者是没注册什么。

调用c的dll注意的事情有

http://blog.chinaunix.net/uid-20551228-id-2826635.html
http://my.oschina.net/kavensu/blog/228827

[DllImport("CDllTest.dll", EntryPoint = "fnCDllTest_NJ", CharSet = CharSet.Unicode)]

        public extern static int fnCDllTest_NJ(int data);

就像这样再把dll和你的c#生成的exe放到一个目录就可以直接调用了。

       3.com的其他注意事件

com的线程模式导致调用失败

http://www.cnblogs.com/manors/archive/2010/05/17/COM_Initialize_STA_MTA.html

http://blog.sina.com.cn/s/blog_56dee71a0100ngrv.html

这里面有介绍,也就是如果com是MTA的在  c/c++调用的时候就需要用CoInitializeEx( NULL, COINIT_MULTITHREADED );来初始化,c#则需要设置[MTAThread]。否则会报错找不到对应的接口。如果是STA  在c/c++调用的时候CoInitialize(NULL); c#里面使用[STAThread] 。   这个问题浪费过我两天的时间。

 

       公司用什么需要什么就直接去学习,学得多了就杂糅了,精力分散了就会导致很多细节的忽视,个人感觉还是先深度理解和掌握再广泛接触,否则对你换工作影响很大的。

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息